9.1 Understand the servlet lifecycle

Summary is found under 4.3 Understand fundamentals of the HttpServlet and related APIs

9.2 Describe and use more advanced elements of the servlet APIs

'Advanced elements' is rather vague. Less advanced elements found under 4.3 Understand fundamentals of the HttpServlet and related APIs

Be careful to associate the right method names to PrintWriter and OutputStream. For example:

  • ServletOutputStream uses getOutputStream and write()
  • PrintWriter uses getWriter() and println() [not getPrintWriter nor write()]


PrintWriter writer = response.getWriter();
writer.println(some text and HTML);


ServletOutputStream out = response.getOutputStream();

addHeader and setHeader

setHeader() overwrites the existing value, or works like addHeader() if the value does not exist
addHeader() adds an additional value


Important: you cannot call sendRedirect() after writing to the response!
The browser URL is updated.

response.sendRedirect("http://catvideos.com"); // full URL, takes a String, cannot take a URL object
response.sendRedirect("foo/stuff"); // relative


The browser URL does not get updated. It can work with absolute (/) and relative paths, which are relative to the original request path. If obtaining the the RequestDispatcher from ServletContext, you cannot use a relative path.

Another trap is that you cannot use forward() after a response is already written to the client, e.g. by outputStream.write() or outputStream.flush(). However, methods such as getWriter().println() are okay, assuming the response is not committed.

The RequestDispatcher interface has two methods:

  • forward(ServletRequest, ServletResponse): used by controllers
  • include(ServletRequest, ServletResponse): rarely used, except for jsp:include tag
RequestDispatcher view = request.getRequestDispatcher("result.jsp");
// or use ServletContext
RequestDispatcher view = getServletContext().getRequestDispatcher("/result.jsp");

Where X is either include or forward, The following request attributes must be set:


The servlet to which a request is forwarded may access the original query string by calling getAttribute("javax.servlet.forward.query_string") on the ServletRequest. All of the above request attributes are always holding the **original request information even if multiple forwarding operations were made.

The execution control returns to the resource that has called the forward() method after the callee resource finishes processing.

SingleThreadModel (deprecated)

Note that SingleThreadModel is deprecated and is not required for the exam.

The SingleThreadModel interface ensures that no two threads will execute concurrently in the servlet’s service method. STM attempts to protect instance variables of the servlet. A container may pool servlet instances or use a queuing strategy.

In reality, only request attributes and local variables are thread-safe, so SingleThreadModel is useless, and therefore deprecated.

9.3 Create filters and use them in web applications

A filter sits between the container and a servlet. It can process the request or response, or both. Filters are independent and can run after each other. They have a lifecycle similar to servlets:

  1. init(FilterConfig config)
  2. doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
  3. destroy()

Request filters can:

  • perform security checks
  • reformat request headers or bodies
  • audit or log requests

Response filters can:

  • compress the response stream
  • append or alter the response stream
  • create a different response altogether

Ordering filters

FilterChain can call either a filter or servlet.

  1. ALL filters with matching URL patterns are located in the order in which they appear
  2. ALL filters with matching <servlet-name> are located in the order in which they appear
  • If there are two filters with the same filter class, with different names, the container is enforced to create two instances of the filter. e.g. web.xml-defined filter and annotated-defined filter using default name (fully-qualified classname)
  • There can't be a duplication of filter name in the Deployment Descriptor. There is no difference if the filter class is different or not.
  • web.xml will override annotated filter with the same name, only one instance will be created
  • When using annotations to define the listeners, servlets and filters, the order in which they are invoked is unspecified.

Example filter

<!-- Declaring a filter mapping to a URL pattern. Can have more than one mapping. -->
<!-- Declaring a flter mapping to a servlet name. Can have more than one mapping. -->
public class BeerRequestFilter implements Filter {
    private FilterConfig fc;
    public void init(FilterConfig config) throws ServletException {
        this.fc = config;
    public void doFilter(ServletRequest req,
                         ServletResponse resp,
                         FilterChain chain)
            throws ServletException, IOException {
        HttpServletRequest httpReq = (HttpServletRequest) req; // cast
        String name = httpReq.getRemoteUser();
        if (name != null) {
            fc.getServletContext().log("User " + name + " is updating");
        chain.doFilter(req, resp); // call next filter or servlet
    public void destroy() {
        // do cleanup stuff

Filter mapping for request-dispatched web resources

A filter is not invoked when the resource upon which the filter is applied gets the request through a request dispatcher, UNLESS an appropriate dispatcher value is specified in filter-mapping. Note that if you use a dispatcher element, then the filter will be invoked ONLY for those dispatcher elements that are listed.

    <!-- zero or more of the below -->

Response filter

Code for response filters goes after:

chain.doFilter(request, response);

A response filter may substitute a different response object, if a servlet has already written to the response. A Wrapper object can be used to save implementing unnecessary methods; extend the Wrapper and implement only the methods you need. The four wrapper classes are:

  • ServletRequestWrapper
  • HttpServletRequestWrapper
  • ServletResponseWrapper
  • HttpServletResponseWrapper
class CompressionResponseWrapper extends HttpServletResponseWrapper {
    // override any methods you want to customize
class MyCompressionFilter implements Filter {
    public void init(FilterConfig cfg) { }
    public void doFilter( request, response, chain) {
        CompressionResponseWrapper wrappedResp = new CompressionResponseWrapper(response);
        chain.doFilter(request, wrappedResp);
        // do compression logic here
    public void destroy() { }


  • * can be used to match servlet names, as well as URL patterns
    REQUEST: Only when the request comes directly from the client (default)
    ASYNC: Only when the asynchronous request comes from the client
    FORWARD: Only when the request has been forwarded to a component
    INCLUDE: Only when the request is being processed by a component that has been included
    ERROR: Only when the request is being processed with the error page mechanism
@WebFilter(filterName = "FilterAnnotatedA",
        urlPatterns = {"/*"},
        servletNames = {"*"},
        initParams = {@WebInitParam(name = "name", value = "Bob")},
        dispatcherTypes = {DispatcherType.REQUEST},
        asyncSupported = true)

Other attributes:

java.lang.String[] value           The URL patterns to which the filter applies
java.lang.String description           The description of the filter
java.lang.String displayName           The display name of the filter
java.lang.String filterName           The name of the filter
java.lang.String largeIcon           The large-icon of the filter
java.lang.String smallIcon           The small-icon of the filter

File Upload / multipart

getParts and getPart methods to iterate over the various mime attachments:

Part getPart(java.lang.String name) // Gets the Part with the given name. 
java.util.Collection<javax.servlet.http.Part> getParts()  // Gets all the Part components of this request, provided that it is of type multipart/form-data.

Files uploaded can be access through tjese methods in ServletRequest (not HttpRequest):
* request.getInputStream(); for binary
* request.getReader(); for character data


An absolute path to a directory on the file system. The location attribute does not support a path relative to the application context. This location is used to store files temporarily while the parts are processed or when the size of the file exceeds the specified fileSizeThreshold setting. The default location is "".


The file size in bytes after which the file will be temporarily stored on disk. The default size is 0 bytes.


The maximum size allowed for uploaded files, in bytes. If the size of any uploaded file is greater than this size, the web container will throw an exception (IllegalStateException). The default size is unlimited.


The maximum size allowed for a multipart/form-data request, in bytes. The web container will throw an exception if the overall size of all uploaded files exceeds this threshold. The default size is unlimited.

    Config is equivalent to:
@WebServlet(name = "FileUploadServlet", urlPatterns = {"/upload"})
@MultipartConfig(location="C:\\xampp\\tomcat\\temp", fileSizeThreshold=1024*1024,
        maxFileSize=1024*1024*5, maxRequestSize=1024*1024*5*5)
public class ServletAnnotatedMultipart extends HttpServlet {
    private final static Logger LOGGER =
    protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) 
                                        throws ServletException, IOException {
        Collection<Part> parts = httpServletRequest.getParts();
        for(Part part: parts) {
        Part part = httpServletRequest.getPart("file");

JSP file:

<!DOCTYPE html>
<html lang="en">
        <title>File Upload</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <form method="POST" action="upload" enctype="multipart/form-data" >
            <input type="file" name="file" id="file" /> <br/>
            <input type="text" value="c:/" name="destination"/>
            <input type="submit" value="Upload" name="upload" id="upload" />


This content should be put in 9.2, but due to its size it is a separate section.
See also: 5.3 Create and use context and init parameters for more details on ServletContextListener

Container initialization and listeners

As Per SRV 10.12 of Servlet Specification,

When a web application is deployed into a container, the following steps must be performed, in this order, before the web application begins processing client requests.

  1. Instantiate an instance of each event listener identified by a <listener> element in the deployment descriptor.
  2. For instantiated listener instances that implement ServletContextListener, call the contextInitialized() method.
  3. Instantiate an instance of each filter identified by a <filter> element in the deployment descriptor and call each filter instance’s init() method.
  4. Instantiate an instance of each servlet identified by a <servlet> element that includes a <load-on-startup> element in the order defined by the load-onstartup element values, and call each servlet instance’s init() method.

Listener ordering

Using web.xml, The order the container uses in building the chain of filters to be applied for a particular request URI is as follows:

  1. First, the <url-pattern> matching filter mappings in the same order that these elements appear in the deployment descriptor.
  2. Next, the <servlet-name> matching filter mappings in the same order that these elements appear in the deployment descriptor.
  • For multiple instances of ServletContextListener, the listeners are invoked in the order of their appearance in web.xml. The "destroyed" method is invoked in the reverse order.
  • The order of listeners when using @WebListener annotation is unspecified.
Object Event Listener Interface Event Class
Web context Initialization and destruction javax.servlet.ServletContextListener ServletContextEvent
Web context Attribute added, removed, or replaced javax.servlet.ServletContextAttributeListener ServletContextAttributeEvent
Session Creation, invalidation, activation, passivation, and timeout javax.servlet.http.HttpSessionListener, javax.servlet.http.HttpSessionActivationListener HttpSessionEvent
Session Attribute added, removed, or replaced javax.servlet.http.HttpSessionAttributeListener HttpSessionBindingEvent
Request A servlet request has started being processed by web components javax.servlet.ServletRequestListener ServletRequestEvent
Request Attribute added, removed, or replaced javax.servlet.ServletRequestAttributeListener ServletRequestAttributeEvent

Ways of classifying listeners

These categories may help you remember:

  • Attribute listeners


  • Other lifecycle listeners


  • Methods in all attribute listeners (except binding listener)


  • Lifecycle events related to sessions (excluding attribute-related events)


  • Lifecycle events related to requests (excluding attribute-related events)


  • Lifecycle events related to servlet context (excluding attribute-related events)


All listeners


HttpSessionEvent (NOT HttpSessionActivationEvent)


You have an attribute class, and you want objects of this type to be notifed when the session to which they’re bound is migrating to and from another JVM. The class must implement Serializable, but the readObject and writeObject methods may not be called.

This listener is not configured in the Deployment Descriptor, but the interface is implemented by entity classes.


HttpSessionBindingEvent (NOT HttpSessionAttributeEvent)

attributeReplaced - ServletRequestAttributeEvent.getValue() returns the replaced value, not the new value

You want to know how many concurrent users there are. In other words, you want to track the active sessions.



valueBound // called BEFORE the object becomes accessible through HttpSession.getAttribute()
valueUnbound // called AFTER the object is removed from the session.

You have an attribute class (a class for an object that will be put in an attribute) and you want objects of this type to be notifed when they are bound to or removed from a session.

This listener is not configured in the Deployment Descriptor, but the interface is implemented by entity classes.




You want to know when a session attribute has been added, removed, or replaced. For more see 4.4 Write code that manages client sessions and cookies




You want to know if an attribute in a web app context has been added, removed, or replaced.




You want to know if a context has been created or destroyed




You want to know when a request attribute has been added, removed, or replaced.




You want to know each time a request comes in, so that you can log it.


If you have questions, corrections, information or examples to add, please comment below.

Add a New Comment