开始用JAVA做J2EE项目的时候, 很多人会遇到乱码问题,这个比较好解决,网上有很多成熟的解决方案,原理也广为大家所知。 我下面只简述一下这种情况下乱码的原因及解决方案:无论是Struts用的action还是、jsp页面、或者其它,最终会被编译成servlet程序由用户来调用。这些servlet是以UNICODE编码的。其实servlet用什么编码并不重要,重要的是servlet的输入和输出以同样的方案编码就不会有乱码。 常见的乱码有两种:一个是表单提交出现乱码;一个是以地址栏传参数出现乱码。 针对第一种形式的乱码,可以在每个jsp页面加上<%@ page pageEncoding="GB18030"%>注:jsp2.0适用; 或者加上<%@ page contentType="text/html; charset=GB18030"%>,“GB2312”、“GBK”、“UTF-8”也可以,反正整个系统中统一就可以。还有一种方式是使用request.setCharsetEncoding("GB18030"),可以使用Filter统一处理。 针对地址栏参数出现乱码的情况,解决方案如下(tomcat适用,其它的没有弄过): 在tomcat的配置文件:server.xml中,找到connector元素,在后面加上一个属性ERIEncoding="GB18030",GB18030是我用的编码方案,在读者的项目中,可以设定成系统中统一使用的编码方案。注意connector元素有两个,一个是针对http,一个是针对https,可以都加上。
下面讨论一下Ajax方式下的乱码问题:首先,如果整个项目使用UTF-8编码,并对request(调用xmlhttp对象的setrequestheader("contentType","text/html;charset=uft-8")方法)进行了正确的编码,就不会有乱码;如果整个项目选用了GB18030方案编码,那么一般情况下会出现乱码。产生的原因就是:xmlhttp使用了UTF-8方案对传递的参数进行编码(这也是整个项目使用UTF-8编码不出现乱码的原因)。我们可以做一个试验对此进行验证: String str ="博客"; String newstr = new String(str.getBytes("UTF-8"),"GB18030"); 如果你的系统使用的WINDOW,项目使用的是GB18030(或者GBK或者GB2312),输出newstr就会是乱码,这个乱码应该与你使用ajax提交中文“博客”所得到的乱码是一致的。 还有个问题, String newstr2=new String(newstr.getBytes("GB18030"),"UTF-8");这样再得到一个新的字符串,这个字符串与初始的字符串str并不相同,最后一个字会是乱码,这个我不知道是什么原因,那们知道原因请告诉我一下。 这样,知道了原理就可以找方法来避免乱码了。经过试验我找到两种方法来解决Ajax的乱码问题(其实原理是一样的): 前提是使用setrequestheader方法进行了正确的编码(POST方式提交数据时,要使用xxx-application-url方案编码,不知写对了没有。呵呵。)。 一、提交中文后,服务器端使用 先使用UTF-8编码提取参数: request.setCharsetEncoding("UTF-8"); String str = request.getParameter("param"); 这样就可以得到正确的参数。 二、可以使用encodeURI进行两次编码,然后在服务器端使用以下方式(这个是我以前的解决方案,显得很土,主要是当时对乱码原理没有弄清): String str = request.getParameter("param"); 然后使用下面的方式进行解码: java.net.URIDecode.decode(str,"UTF-8") 这样同样可以得到正确的参数。
/************************/ 作者:王力猛 (wallimn) 电邮:wallimn@sohu.com 博客:http://wallimn. http://blog.csdn.net/wallimn 时间:2006-11-15 /************************/
今天终于解决了AJAX的中文乱码问题,写篇文章来帮助一下有同样问题的朋友们。我的开发环境:XP, eclipse,使用GB18030编码。 当遇到这个问题时,到网上去查了好多文章,提到几种解决方案,如:全站UTF-8编码;请求头编码为中文;使用javascript中的escape函数。 使用GET方式提交数据的时候,中文问题很好解决,setrequestheader("Content-Type","text/html; encoding=gb18030")就可以了。但这个方法在POST方式中却不起作用。大家都知道GET方式提交数据有长度限制,有时我们必须使用POST方式来提交数据。 但对于POST方式,使用上述的几种方法经过多次测试,问题依旧。我郁闷了好几天。 今天把问题解决了,很简单,是使用escape(或encodeURI,两个函数javascript的函数,功能基本相同,可以查一下相关的帮助),但要使用两次,这是解决问题的关键。 我的例子涉及两个页面,一个是初始页面,一个是AJAX请求处理页面。 初始页面内容如下(hello.jsp): ///////////////////////////////////////////////////////////////////////////////////// <%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <%String path = request.getContextPath();%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>AJAX提交页面</title> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <script type="text/javascript"> function justdo(){ var post="name=王力猛&email=wallimn@sohu.com&bokee=http://wallimn."; post = encodeURI(post); post = encodeURI(post);//两次,很关键 var xmlObj = new ActiveXObject(‘Msxml2.XMLHTTP‘); var URL = ‘<%= path%>/page/act.jsp‘;//文件名需要调整成测试时的相应位置? xmlObj.open (‘post‘,URL,true); xmlObj.setrequestheader("cache-control","no-cache"); xmlObj.setrequestheader("Content-Type","application/x-www-form-urlencoded"); xmlObj.send (post);//注意:POST方式,使用这个来发送内容? } </script> </head> <body> <input type="button" value="提交" onclick="justdo()"/> </body> </html> ///////////////////////////////////////////////////////////////////////////////////// ajax请求处理页面(act.jsp)的内容如下: ///////////////////////////////////////////////////////////////////////////////////// <%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <%String path = request.getContextPath();%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <%@page import="java.net.URLDecoder"%> <html> <head> <title>ajax deal</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> <body> <% //遍历输出参数内容。 for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) { String h = (String) e.nextElement(); String v = request.getParameter(h); String mm = java.net.URLDecoder.decode(v, "UTF-8"); System.out.println("请求参数: " + h + " = " + mm); } %> </body> </html> ///////////////////////////////////////////////////////////////////////////////////// 分析:当调用request.getParameter()函数时,会自动进行一次URI的解码过程,调用时内置的解码过程会导致乱码出现。而URI编码两次后,request.getParameter()函数得到的是原信息URI编码一次的内容。再用可控的解码函数java.net.URLDecoder.decode()就可解出原始的正确的信息。 以上分析纯属个人看法,不知是否正确。
|