• Servlet-中文乱码


     背景

      从Tomcat5.x开始,GET,POST方法提交信息,Tomcat采用不同的方式来处理编码。
      对于GET请求,Tomcat不会考虑使用request.setCharacterEncoding("UTF-8")设置的编码,而会永远使用ISO-8859-1编码。
      对于POST请求,Tomcat会使用request.setCharacterEncoding("UTF-8")设置的编码,如果没有设置,则使用"ISO-8859-1"。

      1 get方式,即请求参数的乱码问题

      原因:
      Tomcat官方文档中The HTTP Connector的配置,其中对URIEncoding属性的描述:
      This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

      翻译:如果没有指定,将使用ISO-8859-1解码URI。

      解决方法,有两种:
      1 根本方法:修改server.xml文件

    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8" />

      2 局部方法:得到一次参数,解码,再编码

    String name=request.getParameter(parameter);
    byte[] arr=name.getBytes("ISO8859-1");
    String nameAfterTransfer=new String(arr,"UTF-8");

      2 post方式,即请求体的乱码问题

      原因:如果没有设置Request,则使用"ISO-8859-1"解码,和你提交页面的编码方式无关。

      解决方法
      Tomcat官方文档中Container Provided Filters的配置,系统提供了一些Filter。其中一个是,org.apache.catalina.filters.SetCharacterEncodingFilter,顾名思义,是设置编码的过滤器。其中有两个属性,encoding,要设置编码的名字,另一个是,ignore,确定是否忽略了由用户代理指定的任何字符编码。如果此属性是true的,则忽略了用户代 
    理,即浏览器提供的任何值。如果false,只有当用户代理没有指定一个编码时,编码才被设置。默认值是false的。

    <filter>
      <filter-name>SetCharacterEncodingFilter</filter-name>
      <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
      <init-param>
        <param-name>encoding</param-name>
        <param-value>自己设置的编码</param-value>
      </init-param>
      <init-param>
        <param-name>ignore</param-name>
        <param-value>true</param-value>
      </init-param>
    </filter>
    <filter-mapping>
      <filter-name>SetCharacterEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

      SetCharacterEncodingFilter类的中的实现,就是设置request.setCharacterEncoding(上面配置中的参数);

      结论:
      我们平时request.setCharacterEncoding("UTF-8")的设置,只是改变请求体的编码方式。

      3 get和post编码问题一起解决的方式:使用useBodyEncodingForURI属性

      useBodyEncodingForURI,如果该值是true,将使用请求体的编码方式编码URI。

      Tomcat官方文档对useBodyEncodingForURI属性是这么解释的,

      如果请求的字符编码是不知道的(不是由浏览器提供,不由setcharacterencodingfilter或使用request.setcharacterencoding方法类似的过滤器),默认的编码是“ISO-8859-1”。而URIEncoding设置对此无影响。

      4 您猜测以下结果会乱码吗?

      在如下html页面中进行操作,该页面已经进行了UTF-8编码,POST提交到后台:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>测试</title>
    </head>
    <body>
    <div>
      <form action="http://localhost/Web/B" method="post">//B是我使用的Servlet类。
        <input type="text" name="name" value="大"/>
        <input type="submit" value="提交表单"/>
      </form>
    </div>
    </body>
    </html>

      答案是:乱码,您答对了吗?
      结论:
        1 Tomcat不会理会我们所提交页面的编码方式,或者说请求中根本不含有编码方式。
      2 如果没有进行request.setCharacterEncoding("UTF-8")设置或者添加过滤器,Tomcat还是会使用"ISO-8859-1"解码。
      3 所以不论提交前页面的编码格式是什么,我们都要设置自己的编码方式。

      终极解决方案
      假设我们要全部使用UTF-8进行解码,终极解决方案就是,
      1 设置server.xml中,useBodyEncodingForURI="true"
      2 设置request.setCharacterEncoding("UTF-8");//本质添加过滤器也就是这么处理的,故没有说添加过滤器。

      就这样,我们就达到了get与post请求全部UTF-8解码的效果。


      最后,如果里面有不对的地方,欢迎大家对我的总结进行指正。

                                                            

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    JAVA WEBSERVICE服务端&客户端的配置及调用(基于JDK)
    An internal error occurred during: "Launching New_configuration"
    Android 创建虚拟机时“提示no system images installed for this target”
    [转] 传说中的WCF(2):服务协定的那些事儿
    [转] 传说中的WCF
    python的包管理
    python入门常用方法(转json,模拟浏览器请求头,写入文件)
    python读写数据篇
    python跳坑手记
    python爬虫入门篇
  • 原文地址:https://www.cnblogs.com/kingofkai/p/5837182.html
Copyright © 2020-2023  润新知