首先可以试下在TOMCAT中的server.xml文件中<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" /> 中添加URIEncoding="UTF-8" 。
1
、编码
编码比较常用的有: UTF-8
, GBK
, GB2312
,
ISO-8859-1
,除了 iso-8859-1
之外的其它三个编码都能很好的支持中文,但它们都兼容 ISO-8859-1
的编码(就是说无论编码怎么改变,只要是 ISO-8859-1
中的字符,永远不会出现乱码)。
这四种编码中, GB2312
是中国规定的汉字编码,也可以说是简体中文的字符集编码;GBK
是 GB2312
的扩展 ,
除了兼容GB2312
外,它还能显示繁体中文,还有日文的假名;
而 UTF-8
虽然也支持中文,但却与GB
码不兼容(编码值不同)。UTF-8
使用的是可变长的 UNICODE
编码,编码可能是 1
位 16
进制(即
ISO-8859-1
中的字符,其编码也是相同的)也有可能是 2
位或 3
位的 16
进制。 UTF-8
的优点是:1
、与CPU
字节顺序无关 ,
可以在不同平台之间交流。 2
、容错能力高 ,
任何一个字节损坏后
,
最多只会导致一个编码码位损失 ,
不会链锁错误 (
如 GB
码错一个字节就会整行乱码 )
,所以在国际化处理中基本都是建议使用 UTF-8
作为编码。
2
、文件的编码
文件编码最常使用的有两种:ANSI
和UTF-8
,光看名字估计你都可以猜到了,ANSI
就是我们保存文件时使用的默认编码,而UTF-8
则需自己设置。对于编码的改变,我使用的工具是NOTEPAD
和ECLIPSE
,NOTEPAD
使用最简单,只要打开文件后在另存为中选择相应的编码就行了,而且它对编码的支持非常好;
而在ECLIPSE
中,只要稍微设置一下就行了,打开首选项,然后选择:常规->
内容类型(ContentType)
,在右边选中你想改变保存编码的文件类型,然后在下方的缺省编码中改变其值,最后点击更新(UPDATE
)按钮即可。
而在其它的编辑器中,默认保存的内容都是GB2312
或者GBK
(NOTEPAD
中对应ANSI
).
而根据前面所说的UTF-8
和GBK,GB2312
等的编码值是不同的这一点,可以知道,如果文件使用了UTF-8
,那么字符编码就必须使用UTF-8
,否则编码值的不同就可能造成乱码。而这也就是为什么那么多的人使用了UTF-8
编码后还会产生乱码的根本原因。(JS
和JSP
都是这个道理)
3
、JSP,STRUTS
等的中文乱码解决方案
其实解决的方法只有一个:
request.setCharacterEncoding(encoding);
方法只有一种,但处理方式就多种多样了,初学者会在JSP 页面上直接使用,而有经验的程序员会使用过滤器。而现在所要说的方法也是过滤器。这里以统一使用UTF-8 作为编码作为例子说明。具体过程就不多说了,网上有很多教程。偷懒一点的,到TOMCAT 中复制就行了。在TOMCAT 的目录下的"webapps"jsp-examples"WEB-INF"classes"filters" 找到SetCharacterEncodingFilter.java 这个类,放到你的程序中并配置好映射路径。配置好后基本上你的乱码问题就解决了。但要映射路径中需要注意的就是不能使用 '*'
<
filter-mapping
>
<
filter-name
>
Set Character Encoding
</
filter-name
>
<
servlet-name
>
*
</
servlet-name
>
</
filter-mapping
>
像上面这样配置的话( 可能也是网上大多教程的做法,想当年也是害苦了我) ,可能你只有JSP 的乱码解决了,要解决STRUTS 的乱码需要映射 *.do 或者 servletActionName 。然后在初始化参数中设置encoding 的值就行了。
<
init-param
>
<
param-name
>
encoding
</
param-name
>
<
param-value
>
UTF-8
</
param-value
>
</
init-param
>
当然,最重要的是要记得根据前面所说的方法,改变你所使用的编辑器保存文件的编码要与使用的字符编码一致。
而在JSP
内容中,还是使用如网上教程所说的那种技俩,在所有页面的页首加入:
<%
@
page language
=
"java" contentType
=
"text
/
html; charset
=
UTF
-
8
"
pageEncoding
=
"UTF
-
8
"
%>
至此,相信JSP,ACTION
都不太可能出现乱码了。
4
、资源文件的乱码解决方案
资源文件谁都知道是国际化支持不可或缺的一部分,如果资源文件都出现乱码了那还了得?其实资源文件的乱码是很好解决的,其原因也是因为使用了UTF-8
做为JSP
编码后,没有相应地改变资源文件的文件编码造成的,所以只要对资源文件保存的编码进行更正后,乱码问题也就解决了。当然,你的中文要使用 native2ascii
命令进行正确的转换。
5
、调用JS
时,JS
内容乱码的解决方案。
其实JS
的乱码还是跟文件的编码有关系的,如果JS
中有中文的话,那JS
文件保存的编码就必须跟调用此JS
的页面编码相同,否则,你的所有中文都要从JSP
页面传给JS
才会显示正常。可以看出对于调用JS
出现的乱码是最容易解决的.
6 、AJAX 提交数据乱码,返回数据乱码的解决方案
万变不离其宗,AJAX
的乱码问题自然跟编码有关了,其实很多人跟我一样想到了对文件编码进行设置,并且在接数据时设置了requet
的编码,在返回的数据时设置了response
的编码一切都以为会很顺利,可是这一切都是徒劳无功的,讨厌的乱码再一次出现在你眼前。在你试了N
多种方法,包括JS
自身的escape,unescape
方法后,你发现乱码仍然猖狂地出现在屏幕上。
其实在试过这N
多方法后,很多人都没发现,解决的方法其实很简单,而且其答案就在我们之前处理的JSP
乱码之中。让我们先看一下AJAX
的经典请求代码
xmlhttp.open( "post", url, async );
xmlhttp.setRequestHeader( "Content-Type", "text/html" );
xmlhttp.send( params );
通过前面的说明,不知道你现在看出端倪了没有。不知道是受了网上教程的影响还是其它方面影响,setRequestHeader 并是万年不变的,也没人想过去改它,而问题就正好出在这个地方。回想一个JSP 页面内容的编码设置,其中有这么一节:
contentType="text/html; charset=UTF-8"
现在知道问题了吧,所以我们要把第二句代码改为:
xmlhttp.setRequestHeader( "Content-Type", "text/html;charset=UTF-8" );
如果提交的是form ,那么设置为"application/x-www-form-urlencoded; charset=UTF-8"
最后别忘了在返回数据时也设置上:
response.setContentType( "text/xml" );
response.setCharacterEncoding( "UTF-8" );
如果要问为什么的话,其实我们可以把xmlhttp 看成是一个临时页面,它由浏览器动态生成,主要作用是在后台获得请求的数据(可以看成是一个高级的iframe )。所以对于普通页面设置的编码,对它也要同样设置。而在servlet 中返回数据为什么要设置contentType 和encoding 其道理也是一样的。众所周知,jsp 的最后形态就是servlet ,而jsp 页首设置的那个内容其实也就是让生成的servlet 中生成这么两句话:
response.setContentType( "text/html" );
response.setCharacterEncoding( "UTF-8" );
而pageEncoding 则是跟jvm 说明了这个页面的内容要使用什么编码保存(这跟之后生成的CLASS 有关系)。所以在servlet 设置response 的编码也是理所当然的了。
response.setContentType("text/xml;charset=UTF-8");
response.setHeader("Pragma", "no-cache"); //HTTP 1.0
response.setDateHeader("Expires", 0); //prevents caching at the proxy server
PrintWriter out = response.getWriter();
out.write(outXML);
out.flush();
out.close();
OK !这样向客户端写的数据中的中文也是UTF-8 编码了,客户端js 脚本获取到request.responseXML 也好,responseText 也好,里面的数据都不会有乱码了
7)解决json在后台传递中的乱码:
a.Action:
PrintWriter out = response.getWriter();
out.print("啊");
b.action:
BufferedReader bf = new BufferedReader(new InputStreamReader(httppost.getResponseBodyAsStream()));
这里得到的bf.readline会是乱码,解决办法为:
在a.Action中 PrintWriter out = response.getWriter(); 前面加上
response.setCharacterEncoding("UTF-8");
在b.Action中修改为BufferedReader bf = new BufferedReader(new InputStreamReader(httppost.getResponseBodyAsStream(),"UTF-8"));