Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the HTTP status code out of a ServletResponse in a ServletFilter?

I'm trying to report on every HTTP status code returned from my webapp. However the status code does not appear to be accessible via the ServletResponse, or even if I cast it to a HttpServletResponse. Is there a way to get access to this value within a ServletFilter?

like image 857
Seth Weiner Avatar asked Aug 19 '09 19:08

Seth Weiner


People also ask

How can I get error code from HTTP response?

Use HttpResponse. getStatusLine() , which returns a StatusLine object containing the status code, protocol version and "reason".

How do you set a status code in HTTP response?

Methods to Set HTTP Status Code Sr.No. This method sets an arbitrary status code. The setStatus method takes an int (the status code) as an argument. If your response includes a special status code and a document, be sure to call setStatus before actually returning any of the content with the PrintWriter.

What does HttpServletResponse do?

Interface HttpServletResponse. Extends the ServletResponse interface to provide HTTP-specific functionality in sending a response. For example, it has methods to access HTTP headers and cookies.

When we get ServletException?

If there is any error with status code either 404 (Not Found) or 403 (Forbidden ), then ErrorHandler servlet would be called. If the web application throws either ServletException or IOException, then the web container invokes the /ErrorHandler servlet.


2 Answers

First, you need to save the status code in an accessible place. The best to wrap the response with your implementation and keep it there:

public class StatusExposingServletResponse extends HttpServletResponseWrapper {      private int httpStatus;      public StatusExposingServletResponse(HttpServletResponse response) {         super(response);     }      @Override     public void sendError(int sc) throws IOException {         httpStatus = sc;         super.sendError(sc);     }      @Override     public void sendError(int sc, String msg) throws IOException {         httpStatus = sc;         super.sendError(sc, msg);     }       @Override     public void setStatus(int sc) {         httpStatus = sc;         super.setStatus(sc);     }      public int getStatus() {         return httpStatus;     }  } 

In order to use this wrapper, you need to add a servlet filter, were you can do your reporting:

public class StatusReportingFilter implements Filter {      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {         StatusExposingServletResponse response = new StatusExposingServletResponse((HttpServletResponse)res);         chain.doFilter(req, response);         int status = response.getStatus();         // report     }      public void init(FilterConfig config) throws ServletException {         //empty     }      public void destroy() {         // empty     }  } 
like image 154
David Rabinowitz Avatar answered Sep 20 '22 22:09

David Rabinowitz


Since Servlet 3.0, there's a HttpServletResponse#getStatus().

So, if there's room for upgrading, upgrade to Servlet 3.0 (Tomcat 7, Glassfish 3, JBoss AS 6, etc) and you don't need a wrapper.

chain.doFilter(request, response); int status = ((HttpServletResponse) response).getStatus(); 
like image 33
BalusC Avatar answered Sep 19 '22 22:09

BalusC