Java Tomcat UTF-8编码问题

8

我正在使用java/jsp/tomcat/mysql开发一个简单的Web应用程序,而最大的问题在于字符编码,因为我需要处理UTF-8编码而不是默认的8851。

首先,我想描述我的程序结构。我使用一个名为Controller.java的Servlet来处理所有请求。因此,在web.xml中,我有一个Controller servlet,它接受所有*.do请求。

然后,这个Controller将根据请求的URL分派请求,例如,如果客户端请求register.do,则Controller将将请求分派到Register.java。

在Register.java中,有一个以请求作为参数的方法,即:

public String perform(HttpServletRequest request) {
    do something with the request...
}

所以问题是,如果我想在这个方法中打印UTF-8编码的内容,会出现乱码。例如,我有一个枚举类型,其中存储了几个常量,枚举类型具有的一个属性是其在繁体中文中的名称。如果我要在此处打印它,则会出现随机字符。
public static void main(Stirng[] args{
    System.out.println(MyEnum.One.getChn());
    logger.info(MyEnum.One.getChn());
}

这段文字用中文打印是正确的。但是,如果我将完全相同的代码放入处理HttpServletRequest的方法中:

public String perform(HttpServletRequest request) {
    System.out.println(MyEnum.One.getChn());
    logger.info(MyEnum.One.getChn());
}

它们被打印为随机字符,但是我可以从调试窗口(Eclipse)中看到变量保存了正确的中文字符。当我想要存储来自request.getParameter()的值时,同样的情况发生了。在调试窗口中,我可以看到变量保存了正确的字符,但是当我将其打印出来或尝试将其存储在数据库中时,它变成了随机字符。我不知道为什么会出现这种行为,并且这阻止了我读取提交的表单值并将其存储到数据库中。是否有人能够给一些提示呢?非常感谢。

1
我不明白你是否担心服务器控制台和日志上的损坏输出,还是担心浏览器响应结果中的损坏输出。你能澄清一下吗? - erickson
2
System.getProperty("file.encoding") 的值是什么? - erickson
我担心的是,在调试窗口中可以看到正确的编码,但当我将变量传递给我的数据库访问对象并将其存储到数据库时,它会变成随机字符。因此,我发现在处理请求的方法中,即使简单地打印UTF-8枚举值也不起作用。 - Evan Chu
当实际存储在数据库中的值可能在从数据库检索过程中被损坏时,您如何知道该值实际上是垃圾值而不是损坏的呢? - erickson
2个回答

12

以下是一个简单的教程,告诉你如何使UTF-8在您的Web应用程序中正常工作:

您需要在应用程序中实现过滤器以进行字符编码:

public class CharacterEncodingFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig)
            throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        servletRequest.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("text/html; charset=UTF-8");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

您需要确保Tomcat的server.xml文件中的连接器元素具有URIEncoding属性,其值为UTF-8。

<Connector port="8080" 
           protocol="HTTP/1.1"
           connectionTimeout="20000"
           URIEncoding="UTF-8"
           redirectPort="8443"/>

同时,您需要在每个 JSP 页面中指定此内容:

<%@page contentType="text/html" pageEncoding="UTF-8"%>

3
实际上,我认为你可以将以下内容放入JSP中,而不是过滤器:<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> - Stijn de Witt
Stijn de Witt的答案对我有用!我没有使用任何过滤器。谢谢。 - rafaelbpa
通用建议 - Ryabinin Sergey

6

如果您需要使用UTF-8编码(实际上,现在每个人都应该使用它),则可以按照Tomcat FAQ中找到的“UTF-8 everywhere HOWTO”进行操作。

http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q8

记得在数据库的文本字段中也需要支持UTF-8。
还要记住,有时将带有非ASCII字符的字符串“打印”到日志文件或控制台可能会受到以下因素的影响:
1. 输出流的字符编码 2. 文件阅读器(例如cat / less / vi)的字符编码 3. 终端的字符编码
最好将值写入文件,然后使用十六进制编辑器检查内容,以确保您获取所需的字节值。

在Eclipse中无处不在的UTF-8:在Eclipse Java项目中使用Unicode/UTF-8 - Stijn de Witt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接