Tomcat中文输出乱码问题

本文记录Java学习过程中遇到的Tomcat中文输出乱码问题~

由于计算机中的数据都是以二进制形式存储的,所以当传输文本时,就会发生字符和字节之间的转换。字符和字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码,如果编码和解码使用的码表不一致,就会导致乱码问题。
 
示例代码:
 
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class ChineseServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        String data = "中国";
        PrintWriter out = response.getWriter();
        out.println(data);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        doGet(request, response);
    }
}
在web.xml中配置完ChineseServlet的映射后,启动Tomcat服务器,在浏览器访问ChineseServlet,浏览器显示如下所示:
 
 
从上图可以看出,浏览器显示的内容都是“??”,说明发生了乱码问题。实际上此处产生乱码的原因是response对象的字符输出流在编码时,采用的ISO-8859-1的编码表,该码表并不兼容中文,会将“中国“编码为“63 63”(在ISO-8859-1的码表中查不到的字符就会显示63)。当浏览器对接收到的数据进行解码时,会采用默认的码表GB2312,将“63”解码为“?”,因此,浏览器将“中国”两个字符显示成了“??”,具体分析如下图所示:
 
 
为了解决上述编码错误,在HttpServletResponse接口中,提供了一个setCharacterEncoding()方法,该方法用于设置字符的编码方式,具体代码如下:
response.setCharacterEncoding("utf-8");
在浏览器中再次访问ChineseServlet,结果如下:
 
 
从上图可以看出,浏览器中显示的乱码不是“??”,但也不是需要输出的“中国”。通过分析发现,这是由于浏览器编码错误导致的,因为response对象的字符输出流设置的编码方式为UTF-8,而浏览器使用的编码方式是GB2312,具体分析过程如下:
 
 
对于上面出现的解码错误,可以通过修改浏览器的解码方式解决。在浏览器中点击菜单栏中的 查看--编码--UTF-8 选项(或者鼠标点击浏览器内部,在弹出的窗口中选择 编码--其它--UTF-8 ),将浏览器的解码方式设置为UTF-8,浏览器的现实结果如下图:
 
 
从上图可以看出,浏览器的现实内容没有出现乱码。由此说明,通过修改浏览器的解码方式可以解决乱码,但是,这样的做法仍然是不可取的,因为你不能让用户每次都去改浏览器的解码方式。为此,在HttpServletResponse对象中,提供了两种解决解码乱码的方案:
 
方案一:
// 设置HttpServletResponse使用utf-8编码
response.setCharacterEncoding("utf-8");
// 通知浏览器使用utf-8解码
response.setHeader("Content-Type", "text/html;charset=utf-8");
方案二:
// 包含第一种方式的两个功能
response.setContentType("text/html;charset=utf-8");
通常情况下,为了使代码更加简洁,会采用第二种方案。

标签: none