How do I define a servlet with @WebServlet annotation?

Annotations is one new feature introduces in the Servlet 3.0 Specification. Previously to declare servlets, listeners or filters we must do it in the web.xml file. Now, with the new annotations feature we can just annotate servlet classes using the @WebServlet annotation.

package org.kodejava.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(
        name = "HelloAnnotationServlet",
        urlPatterns = {"/hello", "/helloanno"},
        asyncSupported = false,
        initParams = {
                @WebInitParam(name = "name", value = "admin"),
                @WebInitParam(name = "param1", value = "value1"),
                @WebInitParam(name = "param2", value = "value2")
        }
)
public class HelloAnnotationServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");

        PrintWriter out = response.getWriter();
        out.write("<html><head><title>WebServlet Annotation</title></head>");
        out.write("<body>");
        out.write("<h1>Servlet Hello Annotation</h1>");
        out.write("<hr/>");
        out.write("Welcome " + getServletConfig().getInitParameter("name"));
        out.write("</body></html>");
        out.close();
    }
}

After you’ve deploy the servlet you’ll be able to access it either using the /hello or /helloanno url.

The table below give brief information about the attributes accepted by the @WebServlet annotation and their purposes.

ATTRIBUTE DESCRIPTION
name The servlet name, this attribute is optional.
description The servlet description and it is an optional attribute.
displayName The servlet display name, this attribute is optional.
urlPatterns An array of url patterns use for accessing the servlet, this attribute is required and should at least register one url pattern.
asyncSupported Specifies whether the servlet supports asynchronous processing or not, the value can be true or false.
initParams An array of @WebInitParam, that can be used to pass servlet configuration parameters. This attribute is optional.
loadOnStartup An integer value that indicates servlet initialization order, this attribute is optional.
smallIcon A small icon image for the servlet, this attribute is optional.
largeIcon A large icon image for the servlet, this attribute is optional.

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central

How do I create zip file in Servlet for download?

The example below is a servlet that shows you how to create a zip file and send the generated zip file for user to download. The compressing process is done by the zipFiles method of this class.

For a servlet to work you need to configure it in the web.xml file of your web application which can be found after the code snippet below.

package org.kodejava.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@WebServlet(urlPatterns = "/zipservlet")
public class ZipDownloadServlet extends HttpServlet {
    public static final String FILE_SEPARATOR = System.getProperty("file.separator");

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            // The path below is the root directory of data to be
            // compressed.
            String path = getServletContext().getRealPath("data");

            File directory = new File(path);
            String[] files = directory.list();

            // Checks to see if the directory contains some files.
            if (files != null && files.length > 0) {

                // Call the zipFiles method for creating a zip stream.
                byte[] zip = zipFiles(directory, files);

                // Sends the response back to the user / browser. The
                // content for zip file type is "application/zip". We
                // also set the content disposition as attachment for
                // the browser to show a dialog that will let user 
                // choose what action will he do to the content.
                ServletOutputStream sos = response.getOutputStream();
                response.setContentType("application/zip");
                response.setHeader("Content-Disposition", "attachment; filename=\"DATA.ZIP\"");

                sos.write(zip);
                sos.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Compress the given directory with all its files.
     */
    private byte[] zipFiles(File directory, String[] files) throws IOException {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ZipOutputStream zos = new ZipOutputStream(baos)) {
            byte[] bytes = new byte[2048];

            for (String fileName : files) {
                String path = directory.getPath() +
                        ZipDownloadServlet.FILE_SEPARATOR + fileName;
                try (FileInputStream fis = new FileInputStream(path);
                     BufferedInputStream bis = new BufferedInputStream(fis)) {

                    zos.putNextEntry(new ZipEntry(fileName));

                    int bytesRead;
                    while ((bytesRead = bis.read(bytes)) != -1) {
                        zos.write(bytes, 0, bytesRead);
                    }
                    zos.closeEntry();
                }
            }

            zos.close();
            return baos.toByteArray();
        }
    }
}

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central

How do I get web application context path?

The context path always comes first in a request URI. The path starts with a “/” character but does not end with a “/” character. When I have a web application with the URL like http://localhost:8080/myapp` then/myapp` is the context path.

For servlets in the default (root) context, this method returns "" (empty string).

package org.kodejava.servlet;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(urlPatterns = "/context-path")
public class ContextPathDemo extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {

        // HttpServletRequest.getContextPath() returns the portion 
        // of the request URI that indicates the context of the 
        // request.
        String contextPath = req.getContextPath();

        PrintWriter pw = res.getWriter();
        pw.print("Context Path: " + contextPath);
    }
}

You’ll get the following information in your browser:

Context Path: /webapp

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central

How do I get servlet request URL information?

In the code example below we will extract information regarding the HTTP (Hypertext Transport Protocol) from the request object (HttpServletRequest). We will extract the protocol used (http / https), server name and its assigned port number. We will also read our application context path, servlet path, path info and the query string. If we combine all the previously mentioned information we will get something equals to the value returned by request.getRequestURL() method.

Let’s check the code snippet below to see what method of the HttpServletRequest class that we can call to get the information regarding the HTTP request object that we can collect.

package org.kodejava.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(urlPatterns = "/url-info")
public class ServletUrlInformation extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Getting servlet request URL
        String url = request.getRequestURL().toString();

        // Getting servlet request query string.
        String queryString = request.getQueryString();

        // Getting request information without the hostname.
        String uri = request.getRequestURI();

        // Below we extract information about the request object path
        // information.
        String scheme = request.getScheme();
        String serverName = request.getServerName();
        int portNumber = request.getServerPort();
        String contextPath = request.getContextPath();
        String servletPath = request.getServletPath();
        String pathInfo = request.getPathInfo();
        String query = request.getQueryString();

        response.setContentType("text/html");
        PrintWriter pw = response.getWriter();
        pw.print("Url: " + url + "<br/>");
        pw.print("Uri: " + uri + "<br/>");
        pw.print("Scheme: " + scheme + "<br/>");
        pw.print("Server Name: " + serverName + "<br/>");
        pw.print("Port: " + portNumber + "<br/>");
        pw.print("Context Path: " + contextPath + "<br/>");
        pw.print("Servlet Path: " + servletPath + "<br/>");
        pw.print("Path Info: " + pathInfo + "<br/>");
        pw.print("Query: " + query);
    }
}

When you access this servlet using the following url http://localhost:8080/url-info?x=1&y=1, you’ll get the following output in your browser:

Url: http://localhost:8080/url-info
Uri: /url-info
Scheme: http
Server Name: localhost
Port: 8080
Context Path:
Servlet Path: /url-info
Path Info: null
Query: x=1&y=1

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central

How do I read servlet context initialization parameters?

package org.kodejava.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = "/context-init-param")
public class ContextInitParameter extends HttpServlet implements Servlet {

    public ContextInitParameter() {
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();

        // Get an instance of ServletContext
        ServletContext context = getServletContext();

        // To read context initialization parameter we can call context.getInitParameter() 
        // and pass the name of initialization parameter to be read. If the named
        // parameter does not exist the returned value will be null.
        //
        // In this example we read an initialization parameter called LOG.PATH
        String logPath = context.getInitParameter("LOG.PATH");
        writer.println("Log Path: " + logPath + "<br/>");

        // Reads all the name of servlet's initialization parameters. If the
        // servlet doesn't have any an empty enumeration will be returned.
        Enumeration<String> enumeration = context.getInitParameterNames();
        while (enumeration.hasMoreElements()) {
            String paramName = enumeration.nextElement();
            String paramValue = context.getInitParameter(paramName);

            writer.println("Context Init Param: [" + paramName + " = " + paramValue +
                    "]<br/>");
        }
    }
}

The context initialization parameter (context-param) look something like this in the web.xml file:

<web-app>
    ...
    <context-param>
        <param-name>locale</param-name>
        <param-value>id_ID</param-value>
    </context-param>
    <context-param>
        <param-name>LOG.PATH</param-name>
        <param-value>F:/Logs</param-value>
    </context-param>
    ...
</web-app>

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central