如何解决Tomcat的乱码
2012-08-15杨丽慧
杨丽慧
(河北民族师范学院 信息中心,河北 承德 067000)
如何解决Tomcat的乱码
杨丽慧
(河北民族师范学院 信息中心,河北 承德 067000)
针对在JSP/Servlet程序设计中,服务器用Tomcat在页面上经常会看到乱码。就这个问题提出几种解决的方法。
tomcat;JSP/Servlet;GET;POST;Filter
开发项目时,用JSP/Servlet编程,服务器用tomcat,经常会看到乱码。所以就乱码的问题同大家探讨一下。
1.页面静态内容乱码
在JSP/Servlet中主要在以下几个地方可以设置编码,<%@page pageEncoding=“UTF-8”%>,建议在每个页面上都加上pageEncoding设定,让应用服务器能正确把JSP文件按照设定的编码转换为Java文件,只要这个pageEncoding设置正确就可以避免静态内容的乱码。有的时候没有设置也没有乱码,那是因为应用服务器还可以读取<%@page content-Type=“text/html;charset=UTF-8”%>中的charset作为备选方案,虽然这是JSP规范中要求的,但是难保有的容器没有实现或实现有BUG,所以有时候在某个应用服务器下 (如Tomcat)不设置pageEncoding也可以,但是同样的页面拿到别的应用服务器下就有可能出现乱码。
2.动态生成内容乱码
新下载的Tomcat没有经过任何特殊的设置,无论是GET和POST都出现乱码。首先设置HTTP Connector(server.xml中监听8080端口的那个Connector),加上URIEncoding=“UTF-8”,消除了GET乱码,再在 JSP页面中第一句加入<%request. setCharacterEncoding(“UTF-8”)%>,消除了POST乱码。通过上面两个设置我们发现,URIEncoding控制的是GET字符集编码,Request的CharacterEncoding控制的是POST字符集编码。
上面提到的<%@page contentType=“text/html;charset=UTF-8”%>,除了声明返回给客户端的流是text/html外,同时设置了Response的CharacterEncoding,相当于执行了Response.setCharacterEncoding (“UTF-8”)这段代码。它保证了服务器端生成的动态内容到达客户端也不会乱码。
但有一种情况下也不会出现乱码,就是如下例这种情况,前提是没有设置Request的CharacterEncoding:
1 protected void doPost(HttpServletRequest request ,HttpServletResponse response) throws ServletException,IOException{
2 response.getWriter().write(request.getParameter(“xxxxx”));
3}
这种情况下提交过来的表单数据其实是ISO-8859-1的编码,而返回给客户端又没有<%@page contentType=“text/html;charset=UTF-8”%>的设置,所以还是ISO-8859-1的编码,但是为什么没有乱码呢?其实已经乱码了,如果在第2行下断点的话,会发现request.getParameter(“xxxxx”)的返回值就是乱码。可以用一句Java代码来解释为什么客户端显示结果没有乱码,如下:
System.out.println(new String(“你好,世界”.get-Bytes(“ISO-8859-1”),“ISO-8859-1”);
很奇怪这句代码,明明是中文,应该用GB2312或GBK之类的字符集编码来getBytes,却用了ISO-8859-1,事实证明,这种互逆操作对字符串本身没有任何影响,只要getBytes和new String的时候字符集编码是一致的就不会引起乱码。
上面这句代码正好说明了数据从客户端POST到服务器端时是ISO-8859-1编码,然后从服务器端写回到客户端还是ISO-8859-1编码,所以就没有造成乱码,如果这里不是直接写回到客户端,而是forward到另一个JSP页面,而这个页面恰好使用了<%@page contentType=“text/html;charset=UTF-8”%>来设置Response的CharacterEncoding,那么在页面中输出xxxxx还会产生乱码,同样用一句Java代码来解释,如下:
System.out.println(new String(“你好,世界”.get-Bytes(“ISO-8859-1”),“UTF-8”));
所以,最后结论是如果想POST到服务器端不乱码就要设置Request的CharacterEncoding,写回到客户端不乱码就要设置 Response的CharacterEncoding,若是JSP页面要设置<%@page contentType=“text/html;charset=UTF-8”%>。
3.AJAX乱码问题 (不借助任何JS框架,像Prototype之类的框架会对GET请求的queryS-tring自动应用encodeURIComponent()编码)
GET请求时,需要对 queryString使用 encodeURIComponent()编码之后再提交到服务器。这是XMLHttpRequest规范所要求的。
POST请求时,不需要使用encodeURIComponent()。
通过对应用程序下断点发现,GET请求和POST请求的数据发送到服务器端都是正常的没有乱码,但是服务器端生成的动态内容写回客户端却是乱码,说明Response的CharacterEncoding设置错误,反过来我们再想一下,根本就没有设置过Response的CharacterEncoding,为什么呢?因为是以AJAX的方式提交表单,返回后不像JSP页面那样有<%@page contentType=“text/html;charset=UTF-8”%>来设置Response的CharacterEncoding,所以就会出错。
综合上述,解决的办法就是各大网站提出的通用解决方案Filter,如果应用没有用到AJAX,只设置Request的CharacterEncoding即可,否则Response的CharacterEncoding也要设置。
TP3
A
2095-3763(2012)02-0062-02
2012-01-05
杨丽慧(1972-),女,河北张家口人,河北民族师范学院信息中心副教授,硕士。