response.setContentType()在Java Filter中重置

时间:2014-07-20 00:16:05

标签: java servlets tomcat7

我试图将gzip压缩文件的内容类型设置为过滤器中正确的mime类型,而不是application / gzip。这是我的一些代码:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,  FilterChain filterChain) throws IOException, ServletException
{
    final HttpServletRequest request = (HttpServletRequest) servletRequest;
    final HttpServletResponse response = (HttpServletResponse) servletResponse;

    String reqUrl = request.getRequestURI();
    if (reqUrl.endsWith(gzExt))
    {
        response.setHeader("Content-Encoding", "gzip");
        response.setContentType("text/javascript");

        System.out.println("Set header " +reqUrl +", " + response.getContentType() );

        filterChain.doFilter(request, response);

        System.out.println("Header now: " + reqUrl + ", " + response.getContentType() );
        return;
    }
}

输出:

Set header /test.js.gz, text/javascript
Header now: /test.js.gz, application/x-gzip

在浏览器中,我看到content-encoding已正确设置为gzip,但content-type仍为application/x-gzip。似乎filterChain.doFilter()正在重置内容类型。

知道如何永久重置内容类型吗?

我没有任何其他过滤器。

2 个答案:

答案 0 :(得分:2)

我在this answer

的帮助下解决了这个问题
private class ForcableContentTypeWrapper extends HttpServletResponseWrapper
{
    public ForcableContentTypeWrapper(HttpServletResponse response)
    {
        super(response);
    }

    @Override
    public void setContentType(String type)
    {
    }
    public void forceContentType(String type)
    {
        super.setContentType(type);
    }
}

然后将上面的代码更改为:

    if (reqUrl.endsWith(gzExt))
    {
        ForcableContentTypeWrapper newResponse = new ForcableContentTypeWrapper(response);
        newResponse.setHeader("Content-Encoding", "gzip");
        newResponse.forceContentType("text/javascript");
        filterChain.doFilter(request, newResponse);
        return;
    }

它不是一个漂亮的解决方法,但它确实有效。

答案 1 :(得分:-1)

首先,您应始终致电(或有充分理由不这样做)

 filterChain.doFilter(request, response);

或在此之后声明的过滤器将不会被调用。

接下来,将调用filterChain.doFilter()移到方法的顶部,然后设置标题,并在web.xml中将过滤器映射声明为最后一个。 这将按预期工作。