Jax-rs 和 servlet 过滤器:IllegalStateException:响应已提交

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

我有 REST API 和 JAX-RS,我需要为响应添加加密,所以我添加了一个 servlet 过滤器:

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);
}

但是我得到了java.lang.IllegalStateException: Response already committed

使用 JAX-RS 和 servlet 过滤器有什么问题吗?有什么方法可以阻止发送响应吗?

谢谢。

JAX-RS 与 servlet 过滤器一起工作得很好。检查您拥有的任何其他过滤器是否已提交响应。

[更新] 如果您使用的是 Jersey,请检查 Jersey's Docs

对于 ContainerResponseFilter。

[更新2]一个例子: 过滤器 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;
    }
}

假设响应体为字符串,并对其进行修改。

现在进入 <servlet> 内的 web.xml:

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

这里是working exmaple