简体   繁体   English

无法压缩发送到JSP的Java服务器响应

[英]Cannot Compress Java Server Response Sent To JSP

I am having trouble in returning compressed response (GZip) from my Java Servlet, to a JSP. 我在将压缩响应(GZip)从我的Java Servlet返回到JSP时遇到麻烦。

Flow : 流 :

  1. Request comes to java servlet 请求来自Java Servlet
  2. Process the request, and create a JSON object, with the response 处理请求,并使用响应创建一个JSON对象
  3. Convert the JSON object to string 将JSON对象转换为字符串
  4. Compress the response string with GZip 用GZip压缩响应字符串
  5. The compressed response string is set as attribute in the request object and control passed to JSP 压缩后的响应字符串在请求对象中设置为属性,并将控制权传递给JSP
  6. In the JSP, the response string (compressed) is printed on screen 在JSP中,响应字符串(压缩)显示在屏幕上

Precautions : 注意事项:

  1. Request object has "Accepting-Encoding" set with "gzip" 请求对象的“ Accepting-Encoding”设置为“ gzip”
  2. Response header has "Content-Encoding" set to "gzip" 响应标头的“ Content-Encoding”设置为“ gzip”
  3. Response content type is set to "application/json" 响应内容类型设置为“ application / json”
  4. Response character encoding is set to "ISO-8859-1" 响应字符编码设置为“ ISO-8859-1”

Result : 结果:

  1. Firefox shows "Content Encoding Error" Firefox显示“内容编码错误”
  2. Chrome shows "Error 330 (net::ERR_CONTENT_DECODING_FAILED): Unknown error." Chrome显示“错误330(net :: ERR_CONTENT_DECODING_FAILED):未知错误。”

Can anyone help point me out, in the right direction please? 有人可以帮我指出正确的方向吗?

The compressed response string is set as attribute in the request object and control passed to JSP 压缩后的响应字符串在请求对象中设置为属性,并将控制权传递给JSP

You shouldn't have forwarded a JSON response to a JSP. 您不应该将JSON响应转发到JSP。 You should have printed the JSON plain to the response and have the JavaScript/Ajax code in your JSP Android app to call the URL of the servlet which returns the JSON. 您应该已经将JSON普通信息打印到响应中,并且 在JSP Android应用中具有 JavaScript / Ajax代码 来调用返回JSON的servlet的URL。 See also How to use Servlets and Ajax? 另请参见如何使用Servlet和Ajax? .

As to the GZIP compression, you shouldn't do it yourself. 至于GZIP压缩,您不应该自己做。 Let the server do itself. 让服务器自己做。

Fix your code to remove all manual attempts to compress the response, it should end up to basically look like this: 修复您的代码,删除所有尝试压缩响应的手动尝试,它应该最终看起来像这样:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String json = createItSomehow();
    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write(json);
}

That's all, if you let your Android app call the URL of the servlet, it'll retrieve the JSON string. 就是这样,如果您让Android应用程序调用servlet的URL,它将检索JSON字符串。

Finally edit the server configuration to turn on automatic GZIP compression. 最后,编辑服务器配置以打开自动GZIP压缩。 In case of for example Tomcat, that would be a matter of adding compression="on" to the <Connector> element in Tomcat's /conf/server.xml file: 以Tomcat为例,可以在Tomcat的/conf/server.xml文件<Connector>元素中添加compression="on"

<Connector ... compression="on">

As per the documentation , the compressable mime types defaults to text/html,text/xml,text/plain . 根据文档 ,可压缩的mime类型默认为text/html,text/xml,text/plain You can configure this to add application/json . 您可以配置它以添加application/json

<Connector ... compression="on" compressableMimeType="text/html,text/xml,text/plain,application/json">

Unrelated to the concrete problem, the response character encoding must be set to UTF-8 which is as per the JSON specification. 具体问题无关必须根据JSON规范将响应字符编码设置为UTF-8

JSPs are for rendering textual data to the client. JSP用于将文本数据呈现给客户端。 GZIP is binary data, even if it is compressed text underneath. GZIP是二进制数据,即使它是下面的压缩文本也是如此。

I suggest using a GZIP servlet filter to compress your data on the fly, instead of doing it programmatically in your business logic. 我建议使用GZIP Servlet过滤器动态压缩数据,而不是在业务逻辑中以编程方式进行压缩。

See this prior question for how to get hold of one off-the shelf: Which compression (is GZIP the most popular) servlet filter would you suggest? 有关如何获得现成的信息,请参见以下先前问题: 您将建议使用哪种压缩(GZIP是最受欢迎的)servlet过滤器?

Failing that, then write your own servlet filter that does the same thing. 失败了,然后编写自己的servlet过滤器来完成相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM