我正在尝试编写一个servlet过滤器,它会根据请求的状态为响应添加标头。我知道我必须在传递给chain.doFilter
之前用HttpServletResponseWrapper包装响应,但是标题永远不会被发送,所以我显然遗漏了一些非常明显的东西。
代码类似于:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(httpServletResponse);
chain.doFilter(request, responseWrapper);
if(responseWrapper.getStatus() < 400)
{
responseWrapper.addHeader("X-Custom-Foobar", "abc");
}
}
在检查完成之前,我是否必须在包装器中捕获以防止响应发送到客户端?
答案 0 :(得分:1)
您需要扩展 HttpResponseWrapper()
并覆盖相应的方法。只使用香草HttpResponseWrapper
本身就完全没有。
答案 1 :(得分:0)
所以关于这个规范的令人沮丧的部分是你必须完全拦截ServletOutputStream
并缓冲它。我最后在这里举例:: https://stackoverflow.com/a/11027170/76343
基类HttpServletResponseWrapper
是完整的直通,只要输出流关闭,对响应的所有进一步修改都会静音。
不幸的是,似乎没有更优雅的方法来实现这一目标。
答案 2 :(得分:0)
这实际上是可能的。但是因为调用 chain.doFilter(request, response)
后响应已经提交,所以我们必须在收到状态码之后,但在提交响应之前设置标头。下面是一个例子:
public class HeadersFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,
ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
chain.doFilter(request, new ResponseWrapper(response));
}
public static class ResponseWrapper extends HttpServletResponseWrapper {
public ResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public void setStatus(int sc) {
super.setStatus(sc);
// SET YOUR HEADERS HERE
// setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
}
}
@Override
public void destroy() {
}
}
答案 3 :(得分:0)
这段代码的顺序颠倒了:
chain.doFilter(request, responseWrapper);
if(responseWrapper.getStatus() < 400)
{
responseWrapper.addHeader("X-Custom-Foobar", "abc");
}
试试这个:
if(responseWrapper.getStatus() < 400)
{
responseWrapper.addHeader("X-Custom-Foobar", "abc");
}
chain.doFilter(request, responseWrapper);
doFilter
方法不会返回到您的方法,直到在线路上发送响应之后。