从JSP返回zip文件

时间:2014-04-14 16:53:21

标签: jsp servlets gzip

如果请求包含一个包含'gzip'的Accept-Encoding标头,那么我写了一个简单的JSP来返回一个JavaScript文件的压缩版本,否则就是解压缩版本。

<%@ page language="java"%>

<%
    boolean zipVersionRequired = false;
    try
    {
            String acceptEncodingHeader = request.getHeader("Accept-Encoding");

            if (acceptEncodingHeader != null && acceptEncodingHeader.indexOf("gzip") != -1)
            {
                    zipVersionRequired = true;
                    response.setHeader("Content-Encoding", "gzip");        
            }
            response.setHeader("Content-Type", "text/javascript");
    }
    catch (java.lang.Throwable t)
    {
    }
%>

<% if (zipVersionRequired == true) {
%>
    <jsp:forward page="/files/zipped/f1.js.gz"/>
<% } else {
%>
<jsp:forward page="/files/unzipped/f1.js"/>
<%
}
%>

有一点值得注意的是,我将Content-Type设置为“text / javascript”,但根据我的浏览器,该响应头的值是“application / x-gzip” - 不确定设置的位置。 Content-Encoding响应头设置为'gzip'。在Chrome开发者工具中,响应本身看起来像一堆奇怪的符号,所以我假设浏览器没有解压缩响应。

我编写了一个servlet来执行相同的工作 - 它根据Accept-Encoding请求标头读取压缩或解压缩文件的内容,并将内容写回客户端。该servlet工作正常,但我想知道我在JSP版本中做错了什么。

我正在使用Tomcat Web服务器,但请不要在连接器上建议使用compression = on设置作为此处任何内容的解决方案,因为在这种情况下这不是一个选项。

谢谢,

1 个答案:

答案 0 :(得分:0)

感谢developerwjk的评论。

这太长了,无法添加为对您的评论的回复,因此张贴为答案(并且有答案;请参阅下文)。

我有兴趣知道为什么你(developerwjk)认为jsp:include比jsp:forward更合适。如果我使用jsp:include,我会收到IllegalStateException。我想我理解的原因 - JSP servlet使用PrintWriter,当我使用jsp:include包含gz文件时,gz后缀是一个公认的mime类型,并被识别为二​​进制类型,因此OutputStream被打开,导致IllegalStateException。那只是我的猜测。

所以我回去使用forward,消除了所有空格(我在生成的Java中检查过)并得到了与originall发布相同的问题 - 所以问题与jsp中的空格无关(不是在使用jsp时:无论如何转发。)

然后我发现它不起作用的原因 - 它是响应中的Content-Type标头。这是由Tomcat设置的,因为默认web.xml文件中的mime-type(application / x-gzip)映射的文件扩展名为(gz)。当我将.gz文件重命名为.xxxxx时,响应中的Content-Type标头与我将其设置为(text / javascript)的内容匹配,浏览器(Chrome)成功解压缩响应并运行javascript。当然我会在war的web.xml中添加一个mime类型的映射,而不是在任何真正的解决方案中使用.xxxxx扩展。

最后一件事 - 我希望jsp:include(其中包含的文件是.xxxxx文件)只要jsp不包含空格就可以工作 - 它不会。我没有得到任何回复内容和此错误(在Chrome上):

Failed to load resource: net::ERR_CONTENT_DECODING_FAILED

我还在嚼着那个。