GET请求和POST请求的中文乱码问题

参考:

 

原始代码:使用Tomcat7.x服务器

    客户端(使用了谷歌验证码):
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
......

<form action="http://localhost:8080/tmp/registServlet" method="get">
    用户名:<input type="text" name="username"/><br/>
    验证码:<input type="text" style="width: 60px;" name="code"/>
    <img src="http://localhost:8080/tmp/kaptcha.jpg" id="code_img" alt="" style="width: 100px; height: 28px;"/>
    <input type="submit" value="登录">
</form>
    servlet程序:
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Session中的验证码
        String token = (String) request.getSession().getAttribute(KAPTCHA_SESSION_KEY);
        //删除Session中的验证码
        request.getSession().removeAttribute(KAPTCHA_SESSION_KEY);

        String code = request.getParameter("code");
        String username = request.getParameter("username");

        if(token != null && token.equalsIgnoreCase(code)){
            System.out.println("保存到数据库:" + username);
            response.sendRedirect(request.getContextPath() + "/ok.jsp");
        }else{
            System.out.println("请不要重复提交表单");
        }
    }
终端输出:

知识回顾

  1.    

  2. tomcat7中关于connector的编码默认为" iso8859-1 "; tomcat8中connector的编码默认为" utf-8 "
    1.  所以 tomcat7默认的解码方式是:输入ISO8859-1的编码方式进行解码 
  3. 浏览器呈现的两种web页面:html页面和jsp页面
  4. 通过表单提交发起的请求:对于表单中的参数, 无论是 通过 get 方法(通过 URL 查询参数)还是 post 方法(通过请求体)提交,浏览器(谷歌、火狐、IE)都会根据页面的 ContentType("text/html; charset=enc") 中指定的编码对表单中的数据进行编码,然后发给服务器。
    • 通过3和4可知:网页(html文件或者jsp文件)在浏览器上的解码方式 就是 当前网页的表单数据提交给服务器前进行编码的方式
  5. jsp文件本身的编码:pageEncoding;服务器发送给客户端浏览器时的内容编码(服务器通过响应头来通知客户端以那种编码形式来进行解码呈现web页面(jsp文件/html页面)的内容): contentType charset
    • contentType 里的 charset="utf-8" ,指的是此web文件输出到浏览器的输出方式为 utf-8 。在这个过程中,一个 JSP 的源文件需要经过三个阶段,两次编码,才能完成一次完整的输出。(服务器响应到客户端的过程)
    • 第三阶段:从服务器到浏览器,这在一过程中用到的指令是contentType。服务器载入和执行由第二阶段生成出来JAVA二进制码,输出的结果,也就是在客户端可见到的结果,在这次输出过程中,由contentType属性中的charset来指定,将UTF8形式的二进制码以charset的编码形式来输出。 如果没有人为设定,则默认的是ISO-8859-1的形式 。---- java web 一次请求编码设置的过程 - 人生已是如此的艰难 - 博客园
      • 由4.可知 如果没有人为设定 contentType属性中的charset,客户端将以ISO-8859-1的编码方式对表单数据进行编码
  6. 客户端发送的数据在请求行中
  7. 客户端发送的数据在请求体中
  8. 对英文字符来说UTF-8编码和ISO-8859-1编码的效果相同
  9. UTF-8编码的格式:一个汉字来三个字节构成,每一个字节会转换成 16进制的编码 ,同时添加上%号

GET乱码原因分析:

    GET请求的全过程:

  1. 客户端浏览器地址栏中向服务器发送请求: http: 服务器地址: port/ 工程名 /regist.jsp
  2. 其中 Regist.jsp中:
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  3. 浏览器中呈现以utf-8编码方式解码的regist.jsp文件
  4. GET方式提交表单,提交表单时表单数据会按照utf-8 来编码数据。因为是GET 方式,这些数据(已经编码好成为字节了)位于http请求行中。
  5. 将http请求发送到服务器
  6. 服务端收到客户端的 HTTP 请求, 中间件/应用服务器 会针对每一次请求分别创建一个 request 对象和 response 对象。
    • request 对象是 服务器端 操作 客户端发送过来的数据 的容器。
    • response 对象是 服务器端 操作 服务端发出的数据 的容器。
  7. Tomcat7.x中默认的编码方式是ISO8859-1,所以也默认使用ISO8859-1对GET请求行中的数据进行解码
  8. 得到 ISO8859-1解码后的乱码

GET乱码解决方案:

  1. 因为原数据的编码方式是utf-8,并且被使用ISO8859-1编码方式进行了解码,所以先使用ISO8859-1对乱码进行编码,得到字节数组,然后再使用UTF-8对字节数据进行解码即可。
String username = request.getParameter("username");//乱码
username = new String(username.getBytes("ISO8859-1"),"UTF-8");//没有乱码

POST乱码原因分析:

    因为: 通过表单提交发起的请求:对于表单中的参数, 无论是 通过 get 方法(通过 URL 查询参数) 还是 post 方法(通过请求体)提交,浏览器(谷歌、火狐、IE)都会根据页面的 ContentType("text/html; charset=enc") 中指定的编码 对表单中的数据进行编码,然后发给服务器。
 所以:post请求体中的数据也是通过UTF-8进行编码后将http请求发送给服务器,然后Tomcat7.x服务器使用默认的ISO8859-1编码方式进行解码,从而导致中文乱码问题。

POST乱码解决方案:

  1. 仍可以通过GET中的解决方式解决POST乱码,即:
String username = request.getParameter("username");//乱码
username = new String(username.getBytes("ISO8859-1"),"UTF-8");//没有乱码
     2. 因为:request 对象是 服务器端 操作 客户端发送过来的数据 的容器。所以可以通过改变request对象的请求体中的编码方式(从而改变了服务器对request对象的请求体中的解码方式),使得Tomcat7.x服务器对request对象的请求体中的默认解码方式变为指定编码的解码方式。
request.setCharacterEncoding("UTF-8");//在获取请求参数前使用
  • 注:因为改变的是request对象的请求体中的编码方式,所以对GET的乱码无效。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值