java中文乱码终极解决方案.docx

上传人:b****7 文档编号:24041311 上传时间:2023-05-23 格式:DOCX 页数:20 大小:29.89KB
下载 相关 举报
java中文乱码终极解决方案.docx_第1页
第1页 / 共20页
java中文乱码终极解决方案.docx_第2页
第2页 / 共20页
java中文乱码终极解决方案.docx_第3页
第3页 / 共20页
java中文乱码终极解决方案.docx_第4页
第4页 / 共20页
java中文乱码终极解决方案.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

java中文乱码终极解决方案.docx

《java中文乱码终极解决方案.docx》由会员分享,可在线阅读,更多相关《java中文乱码终极解决方案.docx(20页珍藏版)》请在冰豆网上搜索。

java中文乱码终极解决方案.docx

java中文乱码终极解决方案

中文乱码终极解决方案

乱码问题好像跟我们中国程序员特别有缘,一直困扰着我们,从开始的JSP乱码问题,STRUTS乱码问题,到现在的AJAX乱码问题,无一不是搞得许多程序员焦头烂额的,整天骂XXX产品对中文支持不了,UTF-8无法使用中文啊什么的,其实这里面被骂的产品中其实99%以上是对中文支持非常好的,而出现乱码的原因只是因为自身对国际化支持以及文件编码等信息的认识不知造成的。

要知道一个产品那么流行,怎么可能对中文支持不了呢,下面就开始一一帮大家解决这些问题。

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这个类,放到你的程序中并配置好映射路径。

配置好后基本上你的乱码问题就解决了。

但要映射路径中需要注意的就是不能使用'*'

SetCharacterEncoding

*

像上面这样配置的话(可能也是网上大多教程的做法,想当年也是害苦了我),可能你只有JSP的乱码解决了,要解决STRUTS的乱码需要映射*.do或者servletActionName。

然后在初始化参数中设置encoding的值就行了。

encoding

UTF-8

当然,最重要的是要记得根据前面所说的方法,改变你所使用的编辑器保存文件的编码要与使用的字符编码一致。

而在JSP内容中,还是使用如网上教程所说的那种技俩,在所有页面的页首加入:

<%@pagelanguage="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的流行,乱码问题也开始困扰着许多刚开始使用它的程序员,幸好我之前对JSP乱码有过一点研究,在遇到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");

最后别忘了在返回数据时也设置上:

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的编码也是理所当然的了。

J2ee中文问题的解决

第一,文件的的编码方式其实就包括两方面:

存和取,存文件必须以一种编码存;读文件也必须以一种编码读。

如果存取按照相同的编码方式,则不会有问题,关键就是很多时候存取的方式不一致,产生乱码。

,如不特别设置取系统默认的编码,中文windows为GBK编码。

从.java->.class过程是,先编写.java文件并按莫种编码方式保存,然后用javac方法编译此文件,注意如.java没按系统默认编码保存则要带encoding参数指明实际编码,否则出错,生成的.class文件存为系统默认编码。

从.jsp->.java->.class,先存为某种编码的.jsp文件,然后tomcat根据pageEncoding读取并转化为servlet存为系统默认编码,然后同上面.java->.class过程。

第二,IDE的encoding为对系统下文件打开的解码方式或保存的编码方式。

特例:

如果.jsp文件有<%@pagelanguage="java"pageEncoding="UTF-8"%>,则eclipse会自动存为UTF-8方式,不管eclipse的encoding是什么,这也是eclipse的聪明之处。

第三,pageEncoding="UTF-8"表示此文件的编码方式,必须与此文件存储方式一致(所以eclipse会首选根据它来存文件),tomcat根据这个来读此.jsp文件并编译为servlet(至于编译成的.java和.class文件应该为tomcat服务器默认编码)。

contentType="text/html;charset=UTF-8"表示当服务器给浏览器传页面文件时编码方式为UTF-8,形式为HTML。

例如:

<%@pagelanguage="java"pageEncoding="UTF-8"%>

<%@pagecontentType="text/html;charset=GBK"%>

 

  test

 

 

  我是个好人

 

表示本jsp文件存为UTF-8字符集,当浏览器打开此页面后,查看原码就会发现源码为GBK字符集。

第四,

request.setCharacterEncoding("UTF-8")是把提交内容的字符集设为UTF-8

response.setCharacterEncoding("UTF-8")可以把页面中的<%@pagecontentType="text/html;charset=iso8859-1"%>换为charset=UTF-8,是给告诉浏览器我这个文件的编码方式。

第五,表单提交:

无论何种表单提交都可以在后台的java文件中通过Stringdes=newString(s.getBytes("iso8859-1"),"UTF-8");来转换成你想要的UTF-8编码方式。

但如果每处都加词句太麻烦,故分post和get两种方式区分提交(tomcat5以后分开处理,之前处理方式一样,即都可以用request.setCharacterEncoding("UTF-8")方法处理,不过tomcat5以后get提交方法用此语句无效)。

1,post提交的数据:

程序加上org.springframework.web.filter.CharacterEncodingFilter过滤器.

encodingFilter

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF8

forceEncoding

true

encodingFilter

*.html

encodingFilter

*.jsp

因为规范要求浏览器提交数据都要用utf8编码,所以这里设置编码方式为UTF8.

特别注意:

a,这个过滤器只是简单的调用:

request.setCharacterEncoding(this.encoding);

在这个语句之前不能调用任何的request.getParameter()方法,否则会设置tomcat的缺省字符集为"ISO-8859-1",并且使setCharacterEncoding的调用失效.所以在这个过滤器之前的过滤器中不能有对getParameter这类方法的调用,比较安全的做法就是把这个过滤器尽量靠前放.

b,在server.xml中不能加上

这个value也设置tomcat的缺省字符集为"ISO-8859-1",使setCharacterEncoding的调用失效.可能其他的value也有这个问题,我没有测试过.

如果要观察http请求参数,可以考虑用过滤器或者其他工具,例如ethereal(

2,get提交的数据:

两种情况:

a,如果从地址栏直接输入汉字,则一般编码为"GBK",需要用

newString(request.getParameter("something").getBytes("ISO-8859-1"),"GBK")

取出

b,如果是页面超连接连接中带的汉字,则编码根据页面编码的不同而不同,如果页面的

content="text/html;charset=utf-8",则在tomcat/conf/server.xml中的配置文件中:

--Defineanon-SSLCoyoteHTTP/1.1Connectoronport8080-->

maxThreads="150"minSpareThreads="25"maxSpareThreads="75"

enableLookups="false"redirectPort="8443"acceptCount="100"

debug="0"connectionTimeout="20000"useBodyEncodingForURI="true"

disableUploadTimeout="true"/>

加上:

useBodyEncodingForURI="true"即可正常使用getParameter取出正确内容.

如果content="text/html;charset=GBK",需用

newString(request.getParameter("something").getBytes("ISO-8859-1"),"GBK")

取出,其他情况类似.

总结:

1,所有页面使用utf8编码,

2,服务器加上过滤器,

3,server.xml中不要使用

4,server.xml文件加上useBodyEncodingForURI="true"

这样应该可以搞定大多数前台的中文问题.至于地址栏输入中文,不支持也罢,一般的程序很少要求

从这里输入.

第六,连接数据库 

1、mysql配置文件:

修改mysql在windows\my.ini里default-character-set=utf-8

2、mysql里数据库和表也都设为utf8_unicode_ci

3、数据库连结:

jdbc:

mysql:

//localhost/mydb?

useUnicode=true&characterEncoding=utf-8

注意,关键就在于此:

此句中间是'&'不是'&'这是因为数据库连结时,在.jsp和.java文件中应该用&号,而XML文件中需要用& 

JSP/Servlet的编码原理

关键字:

JSP,Servlet编码

首先,说说JSP/Servlet中的几个编码的作用

在JSP/Servlet中主要有以下几种设置编码的方式:

1.pageEncoding="UTF-8"

2.contentType="text/html;charset=UTF-8"

3.request.setCharacterEncoding("UTF-8")

4.response.setCharacterEncoding("UTF-8")

其中前两个只能用于JSP中,而后两个可以用于JSP和Servlet中。

1、pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码

众所周知,JSP在服务器上是要先被编译成Servlet的。

pageEncoding="UTF-8"的作用就是告诉JSP编译器在将JSP文件编译成Servlet时使用的编码。

通常,在JSP内部定义的字符串(直接在JSP中定义,而不是从浏览器提交的数据)出现乱码时,很多都是由于该参数设置错误引起的。

例如,你的JSP文件是以GBK为编码保存的,而在JSP中却指定pageEncoding="UTF-8",就会引起JSP内部定义的字符串为乱码。

另外,该参数还有一个功能,就是在JSP中不指定contentType参数,也不使用response.setCharacterEncoding方法时,指定对服务器响应进行重新编码的编码。

2、contentType="text/html;charset=UTF-8"的作用是指定对服务器响应进行重新编码的编码

在不使用response.setCharacterEncoding方法时,用该参数指定对服务器响应进行重新编码的编码。

3、request.setCharacterEncoding("UTF-8")的作用是设置对客户端请求进行重新编码的编码。

该方法用来指定对浏览器发送来的数据进行重新编码(或者称为解码)时,使用的编码。

4、response.setCharacterEncoding("UTF-8")的作用是指定对服务器响应进行重新编码的编码。

服务器在将数据发送到浏览器前,对数据进行重新编码时,使用的就是该编码。

其次,要说一说浏览器是怎么样对接收和发送的数据进行编码的

response.setCharacterEncoding("UTF-8")的作用是指定对服务器响应进行重新编码的编码。

同时,浏览器也是根据这个参数来对其接收到的数据进行重新编码(或者称为解码)。

所以在无论你在JSP中设置response.setCharacterEncoding("UTF-8")或者response.setCharacterEncoding("GBK"),浏览器均能正确显示中文(前提是你发送到浏览器的数据编码是正确的,比如正确设置了pageEncoding参数等)。

读者可以做个实验,在JSP中设置response.setCharacterEncoding("UTF-8"),在IE中显示该页面时,在IE的菜单中选择"查看(V)"à"编码(D)"中可以查看到是"Unicode(UTF-8)",而在在JSP中设置response.setCharacterEncoding("GBK"),在IE中显示该页面时,在IE的菜单中选择"查看(V)"à"编码(D)"中可以查看到是"简体中文(GB2312)"。

浏览器在发送数据时,对URL和参数会进行URL编码,对参数中的中文,浏览器也是使response.setCharacterEncoding参数来进行URL编码的。

以XX和GOOGLE为例,如果你在XX中搜索"汉字",XX会将其编码为"%BA%BA%D7%D6"。

而在GOOGLE中搜索"汉字",GOOGLE会将其编码为"%E6%B1%89%E5%AD%97",这是因为XX的response.setCharacterEncoding参数为GBK,而GOOGLE的的response.setCharacterEncoding参数为UTF-8。

浏览器在接收服务器数据和发送数据到服务器时所使用的编码是相同的,默认情况下均为JSP页面的response.setCharacterEncoding参数(或者contentType和pageEncoding参数),我们称其为浏览器编码。

当然,在IE中可以修改浏览器编码(在IE的菜单中选择"查看(V)"à"编码(D)"中修改),但通常情况下,修改该参数会使原本正确的页面中出现乱码。

一个有趣的例子是,在IE中浏览GOOGLE的主页时,将浏览器编码修改为"简体中文(GB2312)",此时,页面上的中文会变成乱码,不理它,在文本框中输入"汉字",提交,GOOGLE会将其编码为"%BA%BA%D7%D6",可见,浏览器在对中文进行URL编码时,使用的就是浏览器编码。

弄清了浏览器是在接收和发送数据时,是如何对数据进行编码的了,我们再来看看服务器是在接收和发送数据时,是如何对数据进行编码的。

对于发送数据,服务器按照response.setCharacterEncoding—>contentType—>pageEncoding的优先顺序,对要发送的数据进行

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1