乱码的出现是因为编码与解码的不一致造成的,假如你对“中文”两个字进行了gbk格式的保存,却用utf-8格式的解读,是肯定会出现乱码的。
如何避免中文乱码:应用上下统一用一种编码格式。 utf-8或者gbk 建议用utf-8. 虽然占空间,但是通用性强,它属于国际编码格式。相反,gbk是国家级的。
下面简单说下以tomcat为容器的程序响应response的编码流程:
.java--.class
.jsp--.java--.class~~.html
.js--.js
.css--.css
编码涉及到的就这几种流程,而在程序响应中出现中文乱码也就中间的两种情况:
.jsp--.java--.class~~.html:
第一步 jsp的保存编码可以通过<%@ page language="java" pageEncoding="utf-8" 来设置,pageEncoding="utf-8"的意思是该jsp页面将以utf-8的形式保存,在tomcat读取时也同样以utf-8的形式读取;
第二步 然后通过某种(假设A)编码保存为.java(可以是任何编码,即使是ISO-8859,虽然可能出现中文乱码,但不碍事,因为用户看不到。该编码格式可能先参考tomcat的默认编码,如果没有设置可能参考操作系统的默认编码),然后tomcat会继续用A编码读取;
第三步 接着走.class编译流程,类似.java。
最终,会生成html。而html的格式至关重要,它的格式是根据谁来的呢? 有个优先顺序,第一 看response.setCharacterEncoding("UTF-8")是否进行设置 ,没有没则看看jsp中是否设置了<%@ contentType="text/html; charset=utf-8",如果没有则依照
pageEncoding="utf-8"的格式进行保存。 (不同浏览器不一样) 而浏览器非常聪明,它根据响应头信息得到该html的保存编码,然后就用保存编码的编码格式去解码显示。 如图:
而我遇到的乱码情况是这样的:jsp的保存编码为pageEncoding="utf-8",而js的保存编码为gbk(通过eclipse可以看到);当该html在浏览器中以utf-8的格式显示时,它的js也会以utf-8的解码格式去显示,这样 gbk-utf-8就出现乱码了。
解决方法一: 单独为该js设置 <script type="text/javascript" src="<%=basePath%>nccm/js/Dialog.js" charset="utf-8" ></script>编码格式
解决方法二: 修改js的保存编码格式,可以把js复制到文本中,另存为utf-8。然后修改eclipse对js的默认编码为utf-8.window-general-content types -text-javascript,修改为utf-8,update---ok。最后再把文本中的utf-8格式的js复制到eclipse中。
到此,只是简单的描述了一下响应response的编码转换流程。 真正容易出现乱码的地方是 request请求。
request的中文请求乱码分三种情况:1.url参数请求 2.表单 post 参数请求 3.表单 get参数请求
无论哪种情况,在从客户端(浏览器)发送的时候,都采用浏览器的编码方式先编码,然后在服务端再用某一种编码来解码; 之所以出现乱码,是因为在客户端跟服务端所用的编码和解码格式不一致造成的。那么何为浏览器编码? 可以通过(ie)页面-编码进行查看(注意如果你所浏览的页面是由frame构成的,那么你所看到编码为最外层页面的编码,并不一定是当前响应页面的编码《如果外层页面编码和当前响应页面的编码不一致》)。而当前浏览器编码,也就是当前响应页面的编码;如果你在A页面上再次发送请求,那么这次请求所用的编码即浏览器编码为上次响应A页面所用的编码,也就是浏览器展示A页面所用的编码(参考上面响应部分)。
那么,我们确定了浏览器端的编码,服务端解码是依据谁来决定解码格式呢? 首先,表单post方式则通过request.setCharacterEncoding("UTF-8")来决定。ssh2,框架中一般配置有spring、strust2的中文过滤器。org.springframework.web.filter.CharacterEncodingFilter、 org.apache.struts2.dispatcher.FilterDispatcher。 一般情况,都是struts2的过滤器在最后,因为执行完struts2可能就不执行其他过滤器了而直接找对应的action。 CharacterEncodingFilter的格式直接在web.xml中配置,而FilterDispatcher则会取得struts2的默认编码struts.i18n.encoding=UTF-8(在strust2-core.jar下面的default.properties中),如果你没有在struts.xml中设置struts.i18n.encoding的话。 这两个过滤器的作用都是设置request.setCharacterEncoding();
其次,就是url和表单get方式了,他们针对不同的容器,做出的判断也是不一样的。下面以tomcat为例:
对于URL提交的数据和表单中GET方式提交的数据,在接收数据的JSP中设置request.setCharacterEncoding参数是不行的,因为在Tomcat5.0中,默认情况下使用ISO- 8859-1对URL提交的数据和表单中GET方式提交的数据进行重新编码(解码),而不使用该参数对URL提交的数据和表单中GET方式提交的数据进行重新编码(解码)。要解决该问题,应该在Tomcat的配置文件的Connector标签中设置useBodyEncodingForURI或者 URIEncoding属性,其中useBodyEncodingForURI参数表示是否用request.setCharacterEncoding 参数对URL提交的数据和表单中GET方式提交的数据进行重新编码,在默认情况下,该参数为false(Tomcat4.0中该参数默认为 true);URIEncoding参数指定对所有GET方式请求(包括URL提交的数据和表单中GET方式提交的数据)进行统一的重新编码(解码)的编码(不建议使用,可能影响到其他项目)。URIEncoding和useBodyEncodingForURI区别是,URIEncoding是对所有GET方式的请求的数据进行统一的重新编码(解码)(tomcat下的所有项目),而useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新编码(解码),不同的页面可以有不同的重新编码(解码)的编码。所以对于URL提交的数据和表单中GET方式提交的数据,可以修改 URIEncoding参数为浏览器编码或者修改useBodyEncodingForURI为true,并且在获得数据的JSP页面中 request.setCharacterEncoding参数设置成浏览器编码。
而weblogic服务器,网上给出说法需要在weblogic.xml中设置:
input-charset
使用 <input-charset>
元素定义用于读取 GET
和 POST
数据的字符集。例如:
<input-charset>
<resource-path>/foo</resource-path>
<java-charset-name>SJIS</java-charset-name>
</input-charset>
有关详细信息,请参阅确定 HTTP 请求的编码。