How can I get the HTTP status code out of a ServletResponse in a ServletFilter?
Solution 1
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
}
}
Solution 2
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();
Solution 3
Also need to include a wrapper for #sendRedirect, and it would be better to initialize status to '200' rather than '0'
private int httpStatus = SC_OK;
...
@Override
public void sendRedirect(String location) throws IOException {
httpStatus = SC_MOVED_TEMPORARILY;
super.sendRedirect(location);
}
Solution 4
One thing missing from David's answer above is that you should also override the other form of sendError:
@Override
public void sendError(int sc, String msg) throws IOException {
httpStatus = sc;
super.sendError(sc, msg);
}
Solution 5
In addition to David's answer, you'll also want to override the reset method:
@Override
public void reset() {
super.reset();
this.httpStatus = SC_OK;
}
... as well as the deprecated setStatus(int, String)
@Override
public void setStatus(int status, String string) {
super.setStatus(status, string);
this.httpStatus = status;
}
Seth Weiner
Updated on July 08, 2022Comments
-
Seth Weiner almost 2 years
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?
-
David Rabinowitz almost 14 yearsThanks William, I've added it to my sample.
-
manuel aldana over 11 yearsin case somebody does not read until the end of page, watch out Joel's comment below to also set default status=200 and to also override sendRedirect(..)
-
1in9ui5t over 11 yearsI can see situations where your filter mapping placement can impact whether your overriding code gets triggered. For example, a successive filter may not wrap your response but rather replace it. Besides those scenarios, can the status code be set on the response without invoking setStatus, sendError or sendRedirect variants? Is that why you've initialized status to 200?
-
user3621633 about 8 yearsThis was supremely helpful for an older version of Tomcat that's on Servlet spec 2.4. Thank you!
-
Prasanna Kumar H A about 8 yearsWhat about tomcat 6?? servlet version is below 3
-
Prasanna Kumar H A about 8 yearsTomcat 6 doesnt support request.getStatus()... what to do for that
-
Junjie about 8 yearsWonderful! What I need!
-
Prasanna Kumar H A about 8 yearsresponse.sendRedirect() is giving illegalStateExcpetion. I have overridded sendRedirect also as Joel's comment
-
Ralph over 7 yearsThere is
HttpServletRepsone.getStatus()
since Servlet 3.0 - see BalusC`s answer: stackoverflow.com/a/4305235/280244 -
Piyush Upadhyay over 4 years@Joel Can you please mention why to use SC_OK here? I have faced the same issue where the responseWrapper setStatus() is not invoked and httpStatus remains
0
-
Rocky4Ever almost 4 yearsBut I am getting 0 When i do this.