zoukankan      html  css  js  c++  java
  • JavaWeb 之 请求与响应的乱码问题

    一、乱码的原因

      乱码:当编码与解码不一致时,就会出现乱码的情况。(本质:编解码不一致)

      根据乱码又可分为:

          (1)请求乱码:客户端编码与服务器解码不一致

          (2)响应乱码:服务器编码与客户端解码不一致

      编码:将字符转换为二进制的过程称之为编码

      解码:将二进制转换为字符的过程称之为解码

    二、默认的编解码

      1、服务器端(Tomcat)的编解码

          Tomcat 默认是使用 ISO8859-1来编解码的(ISO8859-1是不支持中文的)

          注意:① Tomcat8(包含8)以上版本默认编码格式是 UTF-8

             ② HttpServletRequest 和 HttpServletResponse容器默认编码格式是 ISO-8859-1

      2、客户端的编解码

         浏览器的编码:默认是 GB2312。

          影响form提交数据的编码的因素包括:form的accept-charset属性、html文档的编码方案即document.charset。其中,form的accept-charset是否能够有效,依赖具体浏览器的实现,有些浏览器并不支持,如IE。文档编码方案可以通过document.charset来修改。(<meta charset="UTF-8">)

         浏览器的解码:默认是GBK/GB2312。

          通常来说,浏览器会先按照Content-Type的编码设置来解析文本,然后在解析过程中发现charset设置,再更换编码重新读取。若Content-Type没有设置编码,或者说这个HTML文件根本就不是走的HTTP协议,浏览器通常会猜测编码来解析文本,然后发现charset设置再更换编码读取。

      3、Get 和 Post 解码格式

        request 容器保存的是浏览器的数据,一般是 UTF-8 格式。

        request的方法如:getParameter解码格式会根据Get和Post来设置解码格式。因为Get和Post的取值放在不同地方。所以要分开考虑。

    1. Get是 URL 解码方式。默认解码格式是 Tomcat8 编码格式。所以URL解码是 UTF-8,覆盖掉了 request 容器解码格式
    2. Post 是实体内容解码方式。默认解码格式是request编码格式。与Tomcat8编码格式无关

    三、GET 请求乱码解决

      虽然 Response容器默认以 ISO-8859-1 的编码解析数据
      但是对于get请求提交的数据,在不同版本的 Tomcat中有不同的处理方式,在 Tomcat8 及以上的版本,服务器默认以  UTF-8 的编码方式处理请求参数

      1、方案一:Tomcat 版本8以上不用指定编码格式,默认 utf-8

          而对于 Tomcat8 以下的版本,服务器会默认以ISO-8859-1的编码方式处理请求参数

      2、方案二:编码二次转换(推荐)

          注意:

    utf-8-》iso-8859-1》utf-8          原样
    utf-8-》GBK-》utf-8                  乱码  

          具体参考这篇:编码转换问题

        现在基本都是Tomcat8以上版本 ,所以不存在编码问题,而如果是Tomcat8以下版本解决方案: 

    // 获取请求参数
    String username = req.getParameter("username");
    //1 先以 iso8859-1 进行编码 //2 再以 utf-8 进行解码,手动解码 username = new String(username.getBytes("iso-8859-1"), "UTF-8");

      3、方案三:

        设置指定解码 URL 的编码格式:URIEncoding="UTF-8" (不推荐,依赖服务器,有时候没法设置服务器)

        对于 get 请求需要在修改 Tomcat 服务器里面的server.xml文件的配置:(或者Tomcat目录下的/conf中的 server.xml进行设置)

         

         注意:tomcat8.0以后get请求默认使用UTF-8进行解码,所以此配置只针对tomcat8.0以前的版本

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

      

      4、方案四

        请求参数的编码方式要采用请求体的编码方式(不推荐依赖服务器,有时无法设置服务器)

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

    server.xml:
    <Connector port="8080" protocol="HTTP/1.1"   connectionTimeout="20000"   redirectPort="8443" useBodyEncodingForURI="true" />
    Servlet:
    doGet(){
      request.setCharacterEncoding("utf-8");
    }

      分析

        ① request.setCharacterEncoding("utf-8");只是作用于实体内部,意思就是说对Post有效,对Get无效。

        ② 但是设置useBodyEncodingForURI="true"后URL解码格式和实体内容解码格式一样。

        注意:如果只是设置useBodyEncodingForURI="true那get URL解码格式就是默认iso-8859-1,因为实体内部默认是这个解码格式,即使Tomcat版本8以上默认编码格式为UTF-8也会被iso-8859-1覆盖掉。

    四、POST 请求乱码解决

      Tomcat服务器中 Request 容器默认以 ISO-8859-1 的编码解析数据,因此如果需要在参数中解析中文,需要设置对于 post 请求的乱码,可以设置 request 对象的编码格式为 UTF-8即可。

    request.setCharacterEncoding("UTF-8");
    

        注意

        ① 要写在获取参数前面,不然无法生效;

        ② 设置参数查询的编码;

        ③ 该方法只能对Response容器的请求实体内容的数据编码起作用。POST提交的数据在实体内容中,所以该方法对POST方法有效!

        ④ GET 方法的参数放在 URI 后面,所以对 GET 方式无效;

        扩展也可以为整个 JavaWeb 项目配置字符过滤器。

     1     <filter>
     2         <description>字符集过滤器</description>
     3         <filter-name>encodingFilter</filter-name>
     4         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
     5         <init-param>
     6           <description>字符集编码</description>
     7           <param-name>encoding</param-name>
     8           <param-value>UTF-8</param-value>
     9         </init-param>
    10      </filter>
    11      <filter-mapping>
    12           <filter-name>encodingFilter</filter-name>
    13           <url-pattern>/*</url-pattern>
    14      </filter-mapping>

     

    五、响应乱码解决

      响应乱码解决方案:给服务器和浏览器设置统一的编解码

      方案一:(不推荐使用)

    1 // 设置服务器字符集为 UTF-8
    2 response.setCharacterEncoding("UTF-8");
    3 
    4 // 通过响应头, 设置浏览器也使用 UTF-8 字符集
    5 response.setHeader("Content-Type", "text/html; charset=UTF-8");

      方案二:(推荐使用

    1 // 它会同时设置服务器和客户端都使用 UTF-8 字符集, 还设置了响应头
    2 // 此方法一定要在获取流对象之前调用才有效
    3 response.setContentType("text/html; charset=UTF-8");

    六、总结

      1、中文建议使用post而不是get

      2、Tomcat8版本以上默认是UTF-8对GET方法来说,对POST无效,因为request.getParameter默认调用·iso-8859-1·

      3、get方式参数存放在请求数据包的请求行的URI字段中,以?开始以param=value&parame2=value2的形式附加在URI字段之后,而Post是放在实体内部。

      4、request.setCharacterEncoding(charset);只对消息体中的数据起作用,对于URI字段中的参数不起作用。默认作用于POST,对GET无效。

        当使用request.setCharacterEncoding(charset);时,只能解决表单方法为POST的中文乱码情况,而方法为GET的依然为乱码。

      5、request.setCharacterEncoding(“UTF-8”) 解决 post 乱码

      6、useBodyEncodingForURI=”true”目的是URL解码格式和实体内部解码格式相同。

      7、如果使用JS编程时,在浏览器可以使用encodeURIComponent函数对中文参数进行编码后再拼装参数。

  • 相关阅读:
    Java面向对象(02)--封装
    Java面向对象(01)--初识
    Java基础(10)--数组
    Java基础(09)--方法
    python中format输出常用的3种格式
    python 查找列表中重复元素以及重复元素的次数
    HttpRunner六:创建run.py文件,执行套件并生成测试报告
    HttpRunner五:关联参数的应用,获取上一个接口的返回值,用于当前接口的请求值
    HttpRunner四:testcases、testsuites以及参数化的使用
    HttpRunner中在case2中,使用作为请求参数和预期结果,预期结果中值显示是:LazyString($变量key)
  • 原文地址:https://www.cnblogs.com/niujifei/p/15115058.html
Copyright © 2011-2022 走看看