How to Get the Http Status Code Out of a Servletresponse in a Servletfilter

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

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
}

}

How to return HTTP error code from servlet filter?

You need to cast servletResponse to HttpServletResponse first:

HttpServletResponse response = (HttpServletResponse) servletResponse;

Then use its sendError() method:

response.sendError(HttpServletResponse.SC_FORBIDDEN);

SC_FORBIDDEN stands for code 403.

By the way, you don't redirect to 403 page, you just respond with that status. If you do that, the servlet container will serve a special 403 page to the user. You can configure that page in your web.xml:

<error-page>
<error-code>403</error-code>
<location>/error-403.htm</location>
</error-page>

This instructs the container to serve your custom page /error-403.htm when you set 403 status.

If you want a redirect, you could use response.sendRedirect() (it issues a 302 redirect).

How to set http status code when responding to servlet client from Filter class-method in tomcat

I've implemented a filter for authentication shortly. I've coded something similar to this:

public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain)
{
HttpServletResponse response=(HttpServletResponse) resp;

boolean authenticated=false;
// perform authentication

if (authenticated)
{
chain.doFilter(req, response);
}
else
{
// don't continue the chain
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "BASIC realm=\"Your realm\"");

response.setContentType("what you need");
PrintWriter writer=response.getWriter();

// don't set content length , don't close
}
}

Is it possible to write a servlet filter to take inspect HTTP response codes?

you can wrap your outgoing response using HttpServletResponseWrapper:

class GetStatusWrapper extends HttpServletResponseWrapper {

private int status;

GetStatusWrapper(HttpServletResponse response) {
super(response);
}

@Override
public void setStatus(int sc) {
super.setStatus(sc);
status = sc;
}

public int getStatus() {
return status;
}
}

then in your filter:

public class GetStatusResponseFilter implements Filter {

@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
GetStatusWrapper wrapper;
wrapper = new GetStatusWrapper((HttpServletResponse) response);
filterChain.doFilter(request, wrapper);
System.out.println("status = " + wrapper.getStatus());
}

@Override
public void init(FilterConfig arg0) throws ServletException {
}

@Override
public void destroy() {
}
}

Servlet response filter for non 2xx http code

You need to include the DispatcherType in your @WebFilter declaration:

@WebFilter(urlPatterns={...}, dispatcherTypes={ERROR, REQUEST, ...})
public class ...

How to set response status code in Filter when controller returns ResponseEntity?

With the /string endpoint, you're not modifying the status code. With the /entity endpoint, you explicitly are (you're setting it to 200 by virtue of returning an ok).

Your filter implementation changes the response status code and then proceeds to run the rest of the filter chain -- and then the servlet. And we just established the servlet (your controller) is setting the response status code to something else.

So you need to change the response code after the servlet/controller has done its thing.

Your first thought might be to reimplement your filter like this:

@Component
public class TestFilter implements Filter {

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(req, resp);
} finally {
HttpServletResponse response = (HttpServletResponse) resp;

response.setStatus(205);
}
}
}

But unfortunately, that won't work either! According to the documentation:

Note that postHandle is less useful with @ResponseBody and
ResponseEntity methods for which the response is written and committed
within the HandlerAdapter and before postHandle. That means it is too
late to make any changes to the response, such as adding an extra
header. For such scenarios, you can implement ResponseBodyAdvice and
either declare it as an Controller Advice bean or configure it
directly on RequestMappingHandlerAdapter.

This might have the desired effect you're looking for (note I set to "CHECKPOINT" just to demonstrate the point!):

@ControllerAdvice
public class TestResponseBodyAdvice<T> implements ResponseBodyAdvice<T> {

@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}

@Override
public T beforeBodyWrite(T body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
//
// insert status code of choice here
response.setStatusCode(HttpStatus.CHECKPOINT);

return body;
}

}

Setting response code in Servlet Filter

My mistake was doing response.setStatus(403) what needed to happen was

response.sendError(403);
return;


Related Topics



Leave a reply



Submit