javaweb乱码问题深入分析

今天碰到乱码问题,彻底的梳理一遍。

 

彻底解决乱码问题需要配置:

1. server.xml URIEncoding="UTF-8"

2.server.xml useBodyEncodingForURI="true"

3.web.xml  encoding filter

 

分析过程:

简单的认为:pageEncoding是jsp文件本身的编码;contentType的charset是指服务器发送给客户端时的内容编码。例如:pageEncoding="GBK"。这句话的意思是,告诉JVM 这个jsp本身采用的"GBK"编码,在JSP编译成Servlet传给JVM的时候,就用“GBK”的编码方式将Jsp网页源文件翻译成统一的UTF-8形式的Java字节码。如果不加设定,则JVM默认的用ISO-8859-1这种编码方式。contentType里的charset=gbk,指的是此网页文件输出到浏览器的输出方式为gbk。在这个过程中,一个JSP的源文件需要经过三个阶段,两次编码,才能完成一次完整的输出。第一阶段:将jsp编译成Servlet(.java)文件。用到的指令是pageEncoding,根据pageEncoding=“XXX”的指示,找到编码的规则为“XXX”,服务器在将JSP文件编译成.java文件时会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8编码的JAVA源码(即.java)。
第二阶段:从Servlet文件(.java)到Java字节码文件(.class),从UTF-8到UTF-8。在这一阶段中,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。JAVAC用UTF-8的encoding读取java源码,编译成UTF-8编码的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。这一过程是由JVM的内在规范决定的,不受外界控制。
第三阶段:从服务器到浏览器,这在一过程中用到的指令是contentType。服务器载入和执行由第二阶段生成出来JAVA二进制码,输出的结果,也就是在客户端可见到的结果,在这次输出过程中,由contentType属性中的charset来指定,将UTF8形式的二进制码以charset的编码形式来输出。如果没有人为设定,则默认的是ISO-8859-1的形式。

 

1、pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码。 
2、contentType="text/html;charset=UTF-8"的作用是指定对服务器响应进行重新编码的编码。 
3、request.setCharacterEncoding("UTF-8")的作用是设置对客户端请求进行重新编码的编码。
4、response.setCharacterEncoding("UTF-8")的作用是指定对服务器响应进行重新编码的编码。 
response.setCharacterEncoding("UTF-8")的作用是指定对服务器响应进行重新编码的编码。同时,浏览器也是根据这个参数来对其接收到的数据进行重新编码(或者称为解码)。所以在无论你在JSP中设置response.setCharacterEncoding ("UTF-8")或者response.setCharacterEncoding("GBK"),浏览器均能正确显示中文(前提是你发送到浏览器的数据编码是正确的,比如正确设置了pageEncoding参数等)。

 

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

对于接收数据,要分三种情况。一种是浏览器直接用URL提交的数据,另外两种是用表单的GET和POST方式提交的数据。

 

对于表单中POST方式提交的数据,只要在接收数据的JSP中正确request.setCharacterEncoding参数,即将对客户端请求进行重新编码的编码设置成浏览器编码,就可以保证得到的参数编码正确。有写读者可能会问,那如何得到浏览器编码呢?上面我们提过了,在默认请情况下,浏览器编码就是你在响应该请求的JSP页面中response.setCharacterEncoding设置的值。所以对于POST表单提交的数据,在获得数据的JSP页面中request.setCharacterEncoding要和生成提交该表单的JSP页面的 response.setCharacterEncoding设置成相同的值。 

对于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方式的请求的数据进行统一的重新编码(解码),而useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新编码(解码),不同的页面可以有不同的重新编码(解码)的编码。所以对于URL提交的数据和表单中GET方式提交的数据,可以修改 URIEncoding参数为浏览器编码或者修改useBodyEncodingForURI为true,并且在获得数据的JSP页面中 request.setCharacterEncoding参数设置成浏览器编码。

对于这两处tomcat7是分两种编码方式的。URIEncoding就是针对请求参数的编码设置的,而filter的request.setCharacterEncoding('UTF-8')或者请求header中的content-type中的编码都是针对请求体的。

useBodyEncodingForURI=true是说,请求参数的编码方式要采用请求体的编码方式。当useBodyEncodingForURI=true时,若请求体采用utf-8解析,则请求参数也要采用utf-8来解析。

org.springframework.web.filter.CharacterEncodingFilter具有encoding和forceEncoding两个属性,其中encoding是表示设置request的编码,forceEncoding表示是否同时设置response的编码。

 

 

乱码问题汇总:


1> 在tomcat的server.xml设置<Connector URIEncoding="utf-8"  />, 使用utf8对URI中出现的中文进行decode,例如http://localhost:8080/test/测试.do -> http://localhost:8080/test/%E6%B5%8B%E8%AF%95.do, 这样能够找到对应的controller方法。若不设置使用默认值ISO-8859-1


2> 在tomcat的server.xml设置<Connector useBodyEncodingForURI="true"  /> 能够解决query String的乱码问题。
useBodyEncodingForURI=true -> 使用http header中指定charset进行decode(例如:Content-Type: charset=UTF-8),若未指定,则使用默认值ISO-8859-1
useBodyEncodingForURI=false -> 使用默认值ISO-8859-1


3> 若只配置了URIEncoding="utf-8",则query string的编码也会被设置为utf-8,且http header中设置的charset不会重写这个编码。若同时设置了两项,则对于query string的编码,则与设置useBodyEncodingForURI=true的作用是一样的(会被http header中的charset重写)


4> 建议使用utf-8为主,可以在web.xml 中配置encoding filter来指定默认的编码为utf-8,避免乱码问题的出现。
 <filter>
    <filter-name>encoding_filter</filter-name>
    <filter-class >
      org.springframework.web.filter.CharacterEncodingFilter
    </filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encoding_filter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
 

附:

如果还不能解决:

1.window——》preferrence——》general——》workspace   utf-8

2.在tomcat的catalina.bat文件中set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%的后面加上 -Dfile.encoding="UTF-8"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值