【发布时间】:2021-06-24 00:09:23
【问题描述】:
我有一个简单的测试 servlet,它应该输出一个非 ASCII 字符(右单引号 - ')。在 Tomcat 中,它可以工作,但在 Liberty 中,我得到了垃圾。这是 Liberty 中的错误,是我做错了吗,还是配置问题?
package test;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
try (PrintWriter out = response.getWriter()) {
out.print("’");
out.close();
}
}
}
和 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>test.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/TestServlet</url-pattern>
</servlet-mapping>
</web-app>
来自 Tomcat 的响应是(由 Fiddler 提供):
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Content-Length: 3
Date: Wed, 23 Jun 2021 23:40:07 GMT
’
正文十六进制为:E2、80、99(对于 ' 是正确的 UTF-8)
来自Liberty
HTTP/1.1 200 OK
X-Powered-By: Servlet/3.1
Content-Type: text/html;charset=UTF-8
Content-Length: 3
Content-Language: en-CA
Date: Wed, 23 Jun 2021 23:52:49 GMT
’
该内容的十六进制为:C3、A2、E2、82、AC、E2、84、A2
开发工具 (F12) 匹配 Fiddler。
我试过移动代码
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
在 getWriter 之前和之后(文档说它应该在 getWriter 之前)。有无setCharacterEncoding 以及各种事物、内容类型等。
.java 文件本身以 UTF-8 编码保存。
奇怪的是,内容长度标头对于任一服务器来说都是 3 个字节,但对于 Liberty,实际内容长度是 8 个字节。好像字节被重新编码了?
那么,这里发生了什么?
更新: 根据@pmdinh 的回答取出 out.close() 有效果,但没有解决。这是我最接近正确行为的方式
response.setCharacterEncoding("UTF-8");
try (PrintWriter out = response.getWriter()) {
response.setContentType("text/html;charset=UTF-8");
out.print("’1234");
}
这正确编码它,但现在内容长度错误了 2 个字节。所以响应是
HTTP/1.1 200 OK
X-Powered-By: Servlet/3.1
Content-Type: text/html;charset=UTF-8
Content-Length: 5
Content-Language: en-CA
Date: Thu, 24 Jun 2021 17:50:55 GMT
’1234
但由于内容长度为 2 短,浏览器显示 ’12
还要注意,setCharacterEncoding 和 setContentType 的放置很重要,其他组合会使输出变得更糟(编码不正确)。
【问题讨论】:
标签: java servlets websphere-liberty open-liberty