GET方式请求参数中文乱码问题 [JavaWeb][Servlet]

请求参数中文乱码问题(GET)

同样的我们要解决GET方式下的请求参数中文乱码问题,那么我们首先要知道GET请求方式之下为什么中文数据就会出现乱码?

因为我们GET方式之下的请求参数是在请求行中,是紧接着跟到URL的后面, 但是我们要知道我们传输数据的时候通过HTTP协议发送到服务器端中, 那么我们的HTTP协议中是不支持中文数据的发送的, 所以我们肯定是要采用某种编码的形式进行一个数据的发送, 由于我们的GET方式的请求数据是封装到我们的请求行的URL后面的, 所以我们一般发送Get方式的请求数据的时候我们如果请求参数中有中文数据, 这个时候我们都是将我们的中文数据转换为URL编码的格式, 然后对数据进行一个发送, 将这个URL编码发送给服务器端之后我们的服务器端再解析这个URL编码即可

  • 但是这个时候我们的乱码问题就出现在浏览器的URL编码和tomcat服务器的URL解码上了,我们浏览器将我们的请求参数编码为URL编码的时候采用的字符集就是我们的前端HTML界面使用的字符集, 我们一般都是为UTF-8字符集 , 但是我们的tomcat服务器解码的时候使用到的是ISO-8859-1编码对我们的URL编码进行一个解码, 这个时候肯定是会出现一个乱码问题

那么这个时候我们要如何解决这个乱码问题?

其实如果可以的话我们最简单的解决这个乱码的问题的方式应该是我们既然是使用的UTF-8编码字符集完成的URL编码, 那么我们直接将我们的解码URL的时候的编码也设置为UTF-8编码即可, 但是这个时候对应的会有一些问题的出现, 我们Tomcat服务器对URL进行解码的时候内置的就设置了我们的解码的时候就是使用我们的ISO-8859-1编码, 所以没有给我们提供一个可以设置tomcat服务器对这个URL解码的时候的字符集 — > 所以我们说这种方式就是行不通的

那么我们到底要如何解决?

首先我们要知道, 我们不管是使用UTF-8字符集进行的编码也罢, 或者我们使用的ISO-8859-1字符集解码也罢, 我们其实中间的URL编码都是同一个编码, 我们只不过是对应的将我们的中文数据通过使用UTF-8的编码编码成了对应的编码数据 ,假如这个中文数据到我们的UTF-8字符集中的编码是10000, 这个时候我们编码之后那么自然就拿到了10000这个数据, 但是由于我们的ISO-8859-1字符集中的10000是对应的其他的字符, 所以这个时候产生了乱码 ----> 那么这个时候我们只需要是拿到这个乱码之后的字符我们使用ISO-8859-1字符集对这个乱码后的数据进行一个getBytes()操作, 那么我们就拿到了这个乱码的数据的底层编码, 那么我们其实就是相当于拿到了10000, 然后我们拿到了这个10000之后我们只需要使用UTF-8编码对其进行一个解码就可以了, 就可以获取到没有乱码的正确的中文数据了 — > 这个时候由于10000其实就是对应的UTF-8字符集中的对应此时的中文数据的编码, 那么我们通过这个10000进行一个UTF-8编码字符集下的解码操作, 最终肯定就会得到没有乱码的中文数据

GET请求之下乱码问题的发生以及我们的乱码问题如何解决(图解):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uyoz2r81-1655913538425)(E:\非凡英才\JavaWeb开发\Servlet\图解\GET方式的请求参数又中文的乱码问题以及解决.png)]

我们实际如何使用代码解决的演示:

package com.ffyc.servicedemo;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public class Demo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //假设我们的GET请求参数中的中文数据值就是"张三"
        String s = "张三";

        //对这个中文数据进行UTF-8字符集下的URL编码
        String encode = URLEncoder.encode(s, "utf-8"); //这一步就是模拟我们浏览器对我们的中文数据使用UTF-8字符集进行一个编码
        System.out.println(encode); //输出编码, 我们可以看一下这个URL中文编码的格式

        //对上面我们获得的URL中文编码进行一个ISO-8859-1编码字符集之下的URL解码
        String decode = URLDecoder.decode(encode,"iso-8859-1"); //这一步就是模拟我们1Tomcat服务器对我们的使用UTF-8字符集编码的URL再使用ISO-8859-1字符集进行一个解码, 这个时候就会得到乱码后的数据
        System.out.println(decode); //我们将乱码后的数据也打印出来看一下

        byte[] bytes = decode.getBytes(StandardCharsets.ISO_8859_1); //使用ISO-8859-1字符集对我们的数据进行一个编码操作
        String fin = new String(bytes,StandardCharsets.UTF_8); //使用UTF-8字符集对我们的数据进行一个解码操作, 解码之后就得到了我们正确的中文数据, 此时为"张三"
        System.out.println(fin);
    }
}
我们的Java中为我们提供了两个类专门用于URL的编码和解码:

①URL编码API: URLEncoder类

  • 调用其中的encode()静态方法

②URL解码API: URLDecoder类

  • 调用其中的decoder()静态方法

总结:

中文乱码问题的解决方案:

POST: 设置流的编码

req.setCharacterEncoding(“UTF-8”);

GET: 先编码再解码

new String( username.getBytes(“ISO-8859-1”) , “UTF-8” )

  • 注意: 使用先编码再解码的方式是一种通用的方式, 也就是对于我们的POST方式的请求参数乱码的问题我们也是可以使用先编码再解码的方式来解决

补充:

上面的StandardCharsets.UTF_8和StandardCharsets.IOS_8859_1是两个常量, 就是分别表示"UTF-8" 和 “ISO-8859-1”

  • StandardCharsets是jdk自带的字符编码常量字段
这里我们给出StandardCharsets类的源代码: (注意: 这个类是一个final关键字修饰的类, 不能被继承 ):
public final class StandardCharsets {

    private StandardCharsets() {
        throw new AssertionError("No java.nio.charset.StandardCharsets instances for you!");
    }
    /**
     * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
     * Unicode character set
     */
    public static final Charset US_ASCII = Charset.forName("US-ASCII");
    /**
     * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
     */
    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
    /**
     * Eight-bit UCS Transformation Format
     */
    public static final Charset UTF_8 = Charset.forName("UTF-8");
    /**
     * Sixteen-bit UCS Transformation Format, big-endian byte order
     */
    public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
    /**
     * Sixteen-bit UCS Transformation Format, little-endian byte order
     */
    public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
    /**
     * Sixteen-bit UCS Transformation Format, byte order identified by an
     * optional byte-order mark
     */
    public static final Charset UTF_16 = Charset.forName("UTF-16"); 
}

补充二:

Tomcat8.0之后已经将GET方式的请求参数乱码问题解决了, 解决的方式就是默认解码URL的字符集不再是ISO-8859-1,而是UTF-8了

补充三:

对于get方式的请求参数是在请求行中, 对于请求行中的如果有中文数据的时候就会出现乱码的情况, 因为请求行中的数据如果是中文默认我们就是会进行一个URL编码, 对于英文是直接传输, 对于特殊符号也要进行一个编码, 其实就是使用另一种符号来表示特殊符号(比如使用+(加号)表示空格)

get方式的请求参数是在请求行中, 默认就是使用URL形式的编码, 但是对于英文数据都是兼容的, 但是对于中文数据就要使用URL编码,浏览器会对get方式的请求参数中的中文进行一个默认的URL的编码, 服务器会对get方式的请求参数中的中文进行一个默认的URL解码

Cookie存储的数据是以响应头的形式返回到客户端的, 响应头中不是使用的URL编码, 但是由于我们的HTTP协议中都是不支持中文数据的传输的, 所以即使是Cookie中存储的中文数据我们也要进行一个编码, 编码为URL也是可以, 编码为utf-8也可以, 只要是编码为ACSII中的字符就可以

补充四:

注意: 在服务器中只要是使用流获取或者发送的数据进行前后端交互的时候我们都要设置对应的流的编码字符集为utf-8, 因为我们的tomcat服务器中对于流的编码默认还是ISO-8859-1

  • 比如:
    1. get方式响应数据时
    2. post方式请求数据时
    3. post方式响应数据时

你可能感兴趣的:(JavaWeb,servlet,tomcat,java)