Open Liberty 中的 Servlet 编码问题

吉姆 W 说恢复莫妮卡

我有一个简单的测试 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 用于 ')

自由

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 的放置很重要,其他组合会使输出更糟(编码不正确)。

pmdinh

去除那个

out.close();

这应该可以解决问题。

参考:https : //www.ibm.com/support/pages/apar/PM71666

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章