当前位置: 首页 > news >正文

【祝福伟大的祖国】Java Web 9.2 Request 对象 9.2.5 请求参数中文乱码问题

Java Web

【黑马程序员新版JavaWeb基础教程,Java web从入门到企业实战完整版】

9 Request&Response

文章目录

      • Java Web
      • 9 Request&Response
        • 9.2 Request 对象
          • 9.2.5 请求参数中文乱码问题

9.2 Request 对象

9.2.5 请求参数中文乱码问题

【一个问题】

  1. 将req.html页面的请求方式修改为get

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>获取请求体数据</title>
    </head>
    <body>
    <!--
        action: form 表单提交的请求地址
        method:请求方式,指定为 get
    -->
    <form action="/tomcat-demo/req2" method="get">
        <input type="text" name="username"><br>
        <input type="password" name="password"><br>
        <input type="checkbox" name="hobby" value="1"> 游泳
        <input type="checkbox" name="hobby" value="2"> 爬山 <br>
        <input type="submit">
    </form>
    </body>
    </html>
    
  2. 在Servlet 方法中获取参数,并打印

    @WebServlet("/req2")
    public class RequestDemo1 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //获取username
            String username = req.getParameter("username");
            System.out.println(username);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doGet(req,resp);
        }
    }
    
  3. 启动服务

    这次用户名传去一个中文的。

    在这里插入图片描述

  4. 试试post 请求

    在这里插入图片描述

    仍然是乱码的。

【POST 请求解决方案】

[分析出现中文乱码的原因]

  • POST的请求参数是通过request的getReader()来获取流中的数据
  • TOMCAT在获取流的时候采用的编码是ISO-8859-1
  • ISO-8859-1编码是不支持中文的,所以会出现乱码

[解决方案]

  • 页面设置的编码格式为UTF-8
  • 把TOMCAT在获取流数据之前的编码设置为UTF-8
  • 通过request.setCharacterEncoding(“UTF-8”)设置编码,UTF-8也可以写成小写

[修改]

@WebServlet("/req2")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取username
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

再试一次

在这里插入图片描述

OK。

【GET 请求解决方案】

POST 的解决方案是不适用 Get 请求的。

  • GET请求获取请求参数的方式是request.getQueryString()
  • POST请求获取请求参数的方式是request.getReader()
  • request.setCharacterEncoding(“utf-8”)是设置request处理流的编码
  • getQueryString方法并没有通过流的方式获取数据

[那如何解决]

[get 请求出现乱码的原因]

在这里插入图片描述

  1. 浏览器通过HTTP协议发送请求和数据给后台服务器(Tomcat)

  2. 浏览器在发送HTTP的过程中会对中文数据进行URL编码

  3. 在进行URL编码的时候会采用页面标签指定的UTF-8的方式进行编码,张三编码后的结果为%E5%BC%A0%E4%B8%89

    在这里插入图片描述

  4. 后台服务器(Tomcat)接收到%E5%BC%A0%E4%B8%89后会默认按照ISO-8859-1进行URL解码

  5. 由于前后编码与解码采用的格式不一样,就会导致后台获取到的数据为乱码。

如果把req.html页面的标签的charset属性改成ISO-8859-1 ,后台不做操作,能解决中文乱码问题么?

不能。因为ISO-8859-1本身是不支持中文展示的,所以改了标签的charset属性后,会导致页面上的中文内容都无法正常展示。

[URL 编码]

具体编码过程分两步:

  1. 将字符串按照编码方式转为二进制
  2. 每个字节转为2个16进制数并在前边加上%

举个栗子:张三

张三按照UTF-8的方式转换成二进制的结果为:

1110 0101 1011 1100 1010 0000 1110 0100 1011 1000 1000 1001

http://www.mytju.com/classcode/tools/encode_utf8.asp

在这里插入图片描述

输入张三

在这里插入图片描述

在计算的十六进制结果中,每两位前面加一个%,就可以获取到%E5%BC%A0%E4%B8%89。

在Java中已经为开发者提供了编码和解码的API工具类可以让开发者更快速的进行编码和解码:

举个栗子

package com.dingjiaxing;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

/**
 * ClassName: URLDemo
 * date: 2022/9/12 11:07
 *
 * @author DingJiaxiong
 */

public class URLDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String username = "张三";
        //URL 编码
        String encode = URLEncoder.encode(username,"utf-8");
        System.out.println(encode);

        //URL 解码
        String decode1 = URLDecoder.decode(encode,"utf-8");
        //如果使用另一个编码进行解码
        String decode2 = URLDecoder.decode(encode,"ISO-8859-1");

        System.out.println(decode1);
        System.out.println(decode2);
    }
}

运行结果

在这里插入图片描述

这样就找到了GET 请求中文参数出现乱码的原因了。

  • 浏览器把中文参数按照UTF-8进行URL编码
  • Tomcat对获取到的内容进行了ISO-8859-1的URL解码
  • 在控制台就会出现乱码å¼ ä¸‰(最后是个空格)

[如何解决]

在这里插入图片描述

其实,在进行编码和解码的时候,不管使用的是哪个字符集,他们对应的%E5%BC%A0%E4%B8%89是一致的

那么二进制也是一样的,为:

1110 0101 1011 1100 1010 0000 1110 0100 1011 1000 1000 1001

考虑把乱码内容转换成字节,再把字节转换成张三,在转换的过程中是它们的编码一致,就可以解决中文乱码问题。

【实现】

package com.dingjiaxing;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

/**
 * ClassName: URLDemo
 * date: 2022/9/12 11:07
 *
 * @author DingJiaxiong
 */

public class URLDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String username = "张三";
        //URL 编码
        String encode = URLEncoder.encode(username,"utf-8");
        System.out.println(encode);

        //如果使用另一个编码进行解码
        String decode = URLDecoder.decode(encode,"ISO-8859-1");

        System.out.println(decode); // 现在这里肯定就是å¼ ä¸‰ 个乱码

        //转换为字节数据,编码
        byte[] bytes = decode.getBytes("ISO-8859-1");
        for (byte b : bytes){
            System.out.print(b + " ");
        }

        //此处打印的是:-27 -68 -96 -28 -72 -119
        System.out.println();
        //最后将字节数组转为字符串,解码
        String s =  new String(bytes,"utf-8");
        System.out.println(s); //张三
    }
}

运行结果

在这里插入图片描述

【分析完毕,在Servlet 代码中解决GET 请求乱码问题】

package com.dingjiaxing.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * ClassName: RequestDemo1
 * date: 2022/9/12 9:28
 *
 * @author DingJiaxiong
 */

@WebServlet("/req2")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取username
        String username = req.getParameter("username");
        System.out.println("解决乱码前 : " + username);

        username = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);

        System.out.println("解决乱码后 : " + username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

运行结果

在这里插入图片描述

把request.setCharacterEncoding(“UTF-8”)代码注释掉后,会发现GET请求参数乱码解决方案同时也可也把POST请求参数乱码的问题也解决了
只不过对于POST请求参数一般都会比较多,采用这种方式解决乱码起来比较麻烦,所以对于POST请求还是建议使用设置编码的方式进行。

另外:

Tomcat8.0之后,已将GET请求乱码问题解决,设置默认的解码方式为UTF-8

【小结】

  • 中文乱码解决方案

    POST请求和GET请求的参数中如果有中文,后台接收数据就会出现中文乱码问题,GET请求在Tomcat8.0以后的版本就不会出现了

    POST请求解决方案是:设置输入流的编码

    request.setCharacterEncoding("UTF-8");
    注意:设置的字符集要和页面保持一致
    

    通用方式(GET/POST):先解码,再编码

    new String(username.getBytes("ISO-8859-1"),"UTF-8");
    
  • URL 编码实现方式

    编码:

    URLEncoder.encode(str,"UTF-8");
    

    解码:

    URLDecoder.decode(s,"ISO-8859-1");
    

相关文章:

  • 《When you are old》一如苇中的风,轻柔却难忘
  • JavaFX实战:模拟电子琴弹奏效果,鼠标弹奏一曲piano送给大家
  • 基于VC++和AT89C52单片机的数字存储示波器设计
  • labview与stm32通信
  • OpenHarmony适配移植:X86、ARM、RISC-V、MIPS、LoongArch芯片架构简析
  • DBeaver manual
  • 图解redis(三)——功能篇
  • 数据库的约束和设计
  • Lesson 1 A private conversation
  • 第一季:9SpringMVC中如何解决POST请求中文乱码问题,GET的又如何处理呢【Java面试题】
  • 看了羊了个羊的源码后我发现这个游戏花了最少钱,赚了最多的钱
  • 『 云原生·分布式』分布式基础——Docker容器详解与Docker的安装(Linux与Windows)
  • Web会话跟踪:Cookie与Session
  • 【大数据】Hadoop在呼唤Hive(附一键部署Hive脚本)
  • 8. SQL中Order by和Group by子句的使用简介
  • SegmentFault for Android 3.0 发布
  • ES6系列(二)变量的解构赋值
  • iOS | NSProxy
  • JavaScript标准库系列——Math对象和Date对象(二)
  • MySQL用户中的%到底包不包括localhost?
  • Netty 4.1 源代码学习:线程模型
  • Solarized Scheme
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 创建一个Struts2项目maven 方式
  • 算法-图和图算法
  • 我这样减少了26.5M Java内存!
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • zabbix3.2监控linux磁盘IO
  • ​iOS实时查看App运行日志
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (算法)N皇后问题
  • (转)jQuery 基础
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • ../depcomp: line 571: exec: g++: not found
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .Net6使用WebSocket与前端进行通信
  • .net操作Excel出错解决
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • ??如何把JavaScript脚本中的参数传到java代码段中
  • @selector(..)警告提示
  • [ NOI 2001 ] 食物链
  • [04]Web前端进阶—JS伪数组
  • [AutoSar]状态管理(五)Dcm与BswM、EcuM的复位实现
  • [BUUCTF 2018]Online Tool(特详解)
  • [cocos2d-x]关于CC_CALLBACK
  • [Eclipse] 详细设置护眼背景色和字体颜色并导出
  • [IE9] GPU硬件加速到底是实用创新还是噱头
  • [IE编程] WebBrowser控件中设置页面的缩放
  • [J2ME]url请求返回参数非法(java.lang.illegalArgument)
  • [leetcode] 3Sum
  • [linux c]linux do_div() 函数用法
  • [MICROSAR Adaptive] --- autosar官方文档阅读建议