tomcat编码原理解析
最近又碰到了中文乱码问题,这里我没有把数据库牵扯进来,先说下我的环境,servlet容器使用Tomcat6.0,浏览器FireFox3.0、IE7,涉及字符编码设置的地方我的思路就是编码的地方都统一使用UTF-8。所有页面的charset设置为UTF-8。特别注意Tomcat默认的编码URIEncoding是ISO-8859-1。这样就会造成页面传送参数之间的乱码问题。通过两天的学习,终于发现了其中的原理,下面将做一总结:
一:首先我们看下,一个请求响应的流程
浏览器 IE/FireFox ----------->Servlet容器------------------------>显示页面
编码 使用容器的URIEncoding转码 解码
我把用户发送请求方式不同引起的中文问题划分了四种类型:
1、表单的get提交
浏览器根据页面的charset编码方式对页面进行编码,然后提交至服务器,首先进入对应的字符编码过滤器,(如果有的话),不过Tomcat6.0对于get提交方式采用的是server.xml文件中的URIEncoding编码方式,而并不会采用过滤器中设置的编码,那么根据我的环境设置,jsp页面都使用UTF-8的编码,Servlet容器的URIEncoding也设置为UTF-8,则servlet不用进行转码即可正确解码,获得正常的中文字符串。那么,响应页面的中文因为页面的统一编码(UTF-8)自然也会正常显示(为了保险起见,也可在响应页面添加一段代码:request.setCharacterEncoding("UTF-8")可保证servlet在传输过程中都是UTF-8;)。当然,如果我们Tomcat的URIEncoding设置为其他非UTF-8的编码方式时,页面的内容进入Tomcat解析时,因为Tomcat和页面的编码不统一,就需要转码,例如,如果我们采用Tomcat默认的ISO-8859-1,那么当我们使用request.getParameter("yourVariable ")获取表单参数值时其实Servlet就进行了转码,方式为UTF-8-->ISO-58859-1。代码为:
new String(变量值.getBytes("UTF-8"),"ISO-8859-1");
不过即使这样,我们依然可以使用不恰当的方法显示正常的中文,即逆向转码,例如上面的乱码,我们可以通过ISO8859-1-->UTF-8这种方式还原我们提交时的中文。
new String(乱码.getBytes("ISO-8859-1"),"UTF-8");这样就可以转码,所以综上来看,Tomcat的URIEncoding设置为UTF-8是最好的解决办法。
2、表单的post提交
对于这种方式的请求,request.setCharacterEncoding("一般来自于web.xml中过滤器设置的参数")方法进行编码设置将会产生作用,struts的表单提交方式默认为post方式,那么按照上面我的环境设置,页面,容器,都采用UTF-8编码方式,就不会产生中文乱码问题。
3、页面链接传递中文参数
<% String username = "编辑"; %>
<a href="hello.do?username=<%=username%>">页面中链接传递中文</a>
对于这样方式,我们需要先将参数使用统一的编码方式编码,将编码后的字符放入链接,这里我对参数以UTF-8方式编码,
<% String username = java.net.URLEncoder.encode("编辑","UTF-8"); %>