Ed_
Ed_

Reputation: 378

Jax-rs and servlet filter: IllegalStateException: Response already committed

I have REST API with JAX-RS, and I need to add encryption to the responses, so I added a servlet filter:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
        throws IOException, ServletException {

    ServletRequestWrapper request = new ServletRequestWrapper((HttpServletRequest) servletRequest);
    ServletResponseWrapper response = new ServletResponseWrapper((HttpServletResponse) servletResponse);
    PrintWriter out = response.getWriter();

    filterChain.doFilter(request, response);

    response.getResponse().resetBuffer();
    String servletResponseString = response.toString();
    out.write("Hola"); // Here you can change the response
    out.flush();
    out.close();

    logger.info("AFTER filter, original response: "
            + servletResponseString);
}

But I get java.lang.IllegalStateException: Response already committed

Is there any problem using JAX-RS and servlet filters? Is there any way to retain the response from being send?

Thanks.

Upvotes: 1

Views: 1130

Answers (1)

Peter L
Peter L

Reputation: 312

JAX-RS works fine with servlet filterers. Check if any of the other filters you have has committed the response.

[Update] If you're using Jersey, check Jersey's Docs

for ContainerResponseFilter.

[Update 2] An example: Filter class, JerseyTestFilter.java:

package jersey.example;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;

public class JerseyTestFilter implements ContainerResponseFilter {
@Override 
    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
       String resp = (String) response.getEntity();
       resp += " - filter applied";
      response.setEntity(resp);
      return response;
    }
}

It assumes that the response body is a string and modifies it.

Now this goes to web.xml inside <servlet>:

<init-param>
    <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
    <param-value>jersey.example.JerseyTestFilter</param-value>
</init-param>

Here is the working exmaple

Upvotes: 1

Related Questions