Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To log the status returned by a downstream servlet, call chain.doFilter(request, response) first, then read HttpServletResponse.getStatus(). Reading the status before the chain runs only tells you the response state when the filter was entered. The example below follows the legacy Servlet 3.0 javax.servlet setup used with NetBeans IDE 7, Maven, and Tomcat.

How status interception works in a servlet filter

A filter sits in a request-processing chain. Its doFilter method receives the request, response, and chain; calling chain.doFilter passes control to the next filter or servlet. When that call returns, the downstream code has had an opportunity to set the response status. Oracle’s Java EE 7 Tutorial describes filters as components that can inspect or modify requests and responses, block a request, or interact with external resources.

For simple status logging, cast the response to HttpServletResponse and inspect it after the chain returns. You do not need to wrap the response just to read its status.

Implement the filter for the Servlet 3.0 example

This annotation maps the filter to every matching URL. Replace the broad pattern with a narrower one if the filter should apply only to part of the application.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
package example;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;

@WebFilter(urlPatterns = "/*")
public class InterceptFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse httpResponse =
                (HttpServletResponse) response;

        chain.doFilter(request, response);

        System.out.println("HTTP status: " + httpResponse.getStatus());
    }
}

The placement of the status read matters. If you move the println above chain.doFilter, the filter observes the status at entry, not the status set by the servlet later in the chain. A filter may intentionally omit the chain call when it blocks a request; in that case there is no downstream servlet result to inspect.

Build a small Maven web application in NetBeans IDE 7

The original DZone walkthrough by Chad Lung, published October 23, 2011, uses a Maven Java Web Application named Intercept, removes its generated index.jsp, and adds a MainServlet and an InterceptFilter. Its instructions target NetBeans IDE 7 and an era-appropriate Tomcat deployment, so treat the steps as a historical workflow rather than instructions for current NetBeans or Jakarta Servlet projects.

  1. Create the project: In NetBeans IDE 7, create a Maven Java Web Application named Intercept.
  2. Add the servlet API: For a Servlet 3.0 project, use the Maven dependency shown below. The servlet API should be supplied by the servlet container at runtime; configure the dependency as provided for a container deployment.
  3. Add the servlet and filter: Remove the generated index.jsp if following the historical tutorial, then add MainServlet and the filter class. The servlet should set a response status if you want to verify that the filter observes a value other than the default success status.
  4. Build and deploy: Clean and build the project, deploy the web application to a compatible Tomcat server, and request a URL covered by the filter.
  5. Check the output: The sample writes to standard output; the historical walkthrough checks Tomcat’s catalina.out. The exact log destination depends on the Tomcat installation and how it is started.
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>

Maven Central identifies javax.servlet:javax.servlet-api:3.0.1 as specification version 3.0. It belongs to the legacy javax.servlet namespace, not the newer jakarta.servlet namespace.

Choose the filter mapping and coverage deliberately

Servlet 3.0 annotations can replace a verbose web.xml filter declaration, but they do not remove the need to decide what the filter covers. @WebFilter requires at least one URL pattern through urlPatterns or value; mappings can also target servlet names. Multiple filters execute in mapping-list order, and dispatcher types can constrain execution to REQUEST, ASYNC, FORWARD, INCLUDE, or ERROR.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Choice Effect Use it when
Read before chain.doFilter Observes the response state at filter entry. You need to inspect or log the initial response state.
Read after chain.doFilter Observes the downstream status after the next entity returns. You want to log the status set during normal downstream processing.
Use a URL pattern such as /* Maps the filter to matching application URLs. You intend broad URL coverage; otherwise choose a narrower pattern.
Map by servlet name Limits applicability to the named servlet mapping. You want a particular servlet covered rather than a broad URL set.
Constrain dispatcher types Limits which dispatch categories invoke the filter. You need to decide whether request, async, forward, include, or error dispatches are in scope.

Logging status is different from capturing or changing the response

A status read is observation only; it does not change the response. If the goal is to modify response behavior or capture output, use an HttpServletResponseWrapper. Oracle’s Java EE 7 guidance explains that a filter can wrap the response and provide a stand-in stream; overridden methods such as getWriter() or getOutputStream() can return that stream. This lets the filter control or inspect output before it returns to the client, rather than merely reading the status.

Keep the distinction clear: use the direct response status for logging; use a wrapper when the filter must transform response headers or body data. A wrapper adds responsibility for correctly handling the response stream and should not be introduced solely to print a status code.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Legacy namespace and container compatibility

The NetBeans 7 example is tied to Servlet 3.0 annotations and javax.servlet. A current Jakarta Servlet application may use a different API namespace and dependency, and its container must support that API. The historical tutorial does not document a migration path, so do not mix legacy javax.servlet imports and artifacts with a project configured for jakarta.servlet. Match the imports, Maven dependency, and servlet container to the same API generation.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.