【Servlet篇】如何解决Request请求中文乱码的问题?

前言

前面一篇文章我们探讨了 Servlet 中的 Request 对象,Request 请求对象中封装了请求数据,使用相应的 API 就可以获取请求参数。

【Servlet篇】一文带你读懂 Request 对象

也许有小伙伴已经发现了前面的方式获取请求参数时,会出现中文乱码的情况,本文就是为了解决获取请求参数中文乱码的问题,本文以 POST 请求方式和 GET 请求方式为例,其他的请求方式类似,这里不再赘述。

问题引入

第一步:在 webapps 文件目录下创建 req.html ,在 HTML 添加表单,并且指定页面的请求方式为 get 。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<form action="/servlet-project/demo" 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>

第二步:在 Servlet 获取参数并打印。

@WebServlet("/demo")
public class ServletDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        System.out.println(username);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

第三步:启动服务器,在页面上输入中文。

在这里插入图片描述

第四步:查看控制台输出

image-20230210181009527

修改 form 表单中页面发送请求的方式为 post ,继续上面的步骤进行验证。我们发现,不管是 get 请求还是 post 请求,在发送的请求中如果存在中文,那么服务器接收到的数据都会出现中文乱码的情况,具体该如何解决这个问题呢?

POST请求的解决方案

出现中文乱码的情况的原因:

在 post 请求方式中,我们通过 request 对象的 getReader() 方法来获取流中的数据,其中,页面的编码方式为 UTF-8,而 TomCat 在获取流的时候采取的是 ISO-8859-1 的编码方式,而此方式是不支持中文的。由于编码和解码的方式不相同,ISO-8859-1 编码方式不支持中文,导致了控制台出现中文乱码的情况。

要想解决这个问题,我们只需要将页面的编码方式和 TomCat 在获取流数据之前的编码方式都设置为 UTF-8。通过下面的方式设置 TomCat 获取流对象之前的编码方式:

request.setCharacterEncoding("utf-8");

示例:

@WebServlet("/demo")
public class ServletDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.解决中文乱码的问题
        //设置编码方式为utf-8
        request.setCharacterEncoding("utf-8");

        String username = request.getParameter("username");
        System.out.println(username);
    }

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

此时重新发送 post 请求就会在控制台正常展示中文结果。

我们已经解决了 post 请求中文乱码的问题,但是这个方法不适用于 get 请求,接下来我们探讨 get 请求中文乱码的解决方案。

GET请求的解决方案

在 post 请求方式中,使用流的方式获取请求数据,所以出现中文乱码后我们可以通过设置流的编码方式来解决,但是这样的方式并不适用于 get 请求方式,因为 get 请求使用的并不是流的方式来获取请求数据。get 请求方式获取数据:

request.getQueryString();

get 请求方式出现乱码的原因分析:

浏览器通过 HTTP 协议发送请求和数据到服务器,在这个过程中会对中文进行 URL 编码,编码的方式为页面指定的 UTF-8,服务器接收到这个编码的数据以后会按照 ISO-8859-1 的编码方式进行 URL 解码,由于前后编码的方式不同导致了中文乱码。ISO-8859-1 本身是不支持中文的,所以即使我们修改页面的编码方式为 ISO-8859-1 编码也不能解决中文乱码的问题。

image-20230210204128161

那么什么是 URL 编码,URL 解码呢?我们如何解决 get 请求方式中文乱码的问题?

URL 编码的大致过程是这样的,首先,将字符串按照编码的方式转换为二进制,然后每个字节转换为 2 个 16 进制的数据并在前面加上 %

示例:将 张三 进行 URL 编码

第一步:按照 UTF-8 的方式,找到张三两个汉字对应的十进制并转换为二进制

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

第二步:每个字节转换为 2 为 16 进制数,并且在前面加上 %

%E5%BC%A0%E4%B8%89

Java 中提供编码和解码的 API 工具类让我们更加快速的进行编码和解码的操作。

编码:

java.net.URLEncoder.encode("需要被编码的内容","字符集(UTF-8)")

解码:

java.net.URLDecoder.decode("需要被解码的内容","字符集(UTF-8)")

知道了乱码产生的原因,我们就来解决这个问题。

image-20230210203936986

从上图可以看出,不管使用哪一种字符集,其对应的 %E5%BC%A0%E4%B8%89 都是相同的,即二进制数据是相同的,所以我们可以将乱码的数据转化为字节,再把字节转换为正确的中文汉字,在转换的过程中保证编码的一致,这样就解决了中文乱么的问题。具体实现步骤为:

  • 获取乱码数据对应的二进制数组
  • 按照 UTF-8 的形式获取二进制数据对应的字符串

示例:

public class URLDemo {

  public static void main(String[] args) throws UnsupportedEncodingException {
        String username = "张三";
        //1. URL编码
        String encode = URLEncoder.encode(username, "utf-8");
        System.out.println(encode);
        //2. URL解码
        String decode = URLDecoder.decode(encode, "ISO-8859-1");

        System.out.println(decode); //此处打印的是对应的乱码数据

        //3. 转换为字节数据,编码
        byte[] bytes = decode.getBytes("ISO-8859-1");
        for (byte b : bytes) {
            System.out.print(b + " ");
        }
		//此处打印的是:-27 -68 -96 -28 -72 -119
        //4. 将字节数组转为字符串,解码
        String s = new String(bytes, "utf-8");
        System.out.println(s); //此处打印的是张三
    }
}

回到开始的问题,解决 get 请求中请求参数的中文乱码问题:

@WebServlet("/demo")
public class ServletDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String username = request.getParameter("username");
        System.out.println("解决乱码前:"+username);


        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);

        username = new String(bytes, StandardCharsets.UTF_8);

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

    }

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

同样,这种方式也适用于 post 请求方式解决中文乱码问题。

重点:在 TomCat 8 以后,get 请求方式的中文乱码的问题已经解决,其解决的思路就是官方将解码的方式由原来的 ISO-8859-1 转换为 UTF-8。所以,如果你的 Maven 坐标中配置的是 TomCat 8 以后的版本,get 请求方式不再出现乱码。


你问我青春还剩几年?我的回答是,趁现在,正当时。身边朋友都在问我怎样学好一门编程语言,怎样学好Java?怎样通过 Java 找到一份满意的工作?推荐学习此专栏:Java编程基础教程系列(零基础小白搬砖逆袭)

下期见。

<think>好的,用户问的是Servlet获取请求信息出现中文乱码怎么解决。我得先回忆一下处理这个问题的常见方法。首先,中文乱码通常是因为编码不一致,比如客户端发送的是UTF-8,而服务器端解析的时候用的是ISO-8859-1或者其他编码。那常见的场景有GET和POST请求,这两种的处理方式可能不同。 首先想到POST请求的处理。因为POST的请求体是通过request.getParameter()读取的,所以应该在获取参数之前设置请求体的编码。通常的做法是在Servlet里调用request.setCharacterEncoding("UTF-8"),但记得这个方法只对POST有效,对GET不起作用。而且,必须在第一次调用getParameter之前设置,否则可能无效。 然后是GET请求问题。GET请求的参数是通过URL传递的,而Tomcat等服务器对URL的解码方式可能有默认的ISO-8859-1。这时候,如果URL中有中文参数,服务器解码就会乱码解决方法是修改服务器的配置,比如在Tomcat的server.xml里,找到Connector标签,添加useBodyEncodingForURI或者URIEncoding="UTF-8"属性。不过用户可能没有权限改服务器配置,这时候就需要在代码里处理。比如用String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8")这种方式来手动转码。 另外,前端的页面编码也很重要。如果表单提交的页面不是UTF-8编码,比如HTML里没有设置<meta charset="UTF-8">,或者表单的enctype不对,也可能导致乱码。这时候需要检查前端代码,确保表单的编码和服务器一致。 还有可能是数据库的编码问题,如果数据存储时编码不一致,也可能出现乱码。不过用户的问题集中在获取请求信息时,所以可能暂时不需要考虑数据库,但可以提醒用户检查整个数据流的编码是否统一。 总结下来,解决步骤应该是: 1. 处理POST请求:设置request.setCharacterEncoding("UTF-8")。 2. 处理GET请求:修改服务器配置或在代码中手动转码。 3. 确保前端页面使用UTF-8编码。 4. 检查服务器和数据库的编码设置。 需要分步骤解释,并给出具体的代码示例,比如如何在Servlet中设置编码,如何修改Tomcat配置,以及前端需要注意的地方。同时要提醒用户注意不同应用服务器可能有不同的配置方式,比如Tomcat和Jetty可能有差异,但常见的是Tomcat的例子。还要提到在过滤器(Filter)中统一设置编码,这样可以避免在每个Servlet中都写一遍,提高代码的复用性。 可能用户遇到的场景是表单提交后出现乱码,或者是URL参数乱码。需要分别说明这两种情况的处理方法。同时,要确保用户知道设置编码的顺序,比如在获取参数之前设置request的编码,否则可能无效。 另外,可能需要解释为什么GET和POST的处理方式不同,因为GET参数在URI中,而POST在请求体中,所以服务器处理的方式不同。比如Tomcat对URI的解码默认不是UTF-8,而POST的请求体可以通过setCharacterEncoding来设置。 最后,确保回答结构清晰,分点列出解决方案,并给出代码示例和配置示例,方便用户理解和实施。</think>### Servlet中文乱码问题解决方案(分步骤说明) --- #### 一、问题原因 中文乱码的核心原因是**客户端编码与服务器解码方式不一致**,常见场景: 1. POST请求体未设置UTF-8解码 2. GET请求URL参数未统一编码 3. 前端页面编码与服务器不匹配 4. 服务器容器默认编码问题(如Tomcat默认ISO-8859-1) --- #### 二、解决方案 --- ##### 1. 处理POST请求乱码 **核心方法**:在获取参数前设置请求体编码 ```java protected void doPost(HttpServletRequest request, HttpServletResponse response) { // 必须放在所有getParameter()之前 request.setCharacterEncoding("UTF-8"); String username = request.getParameter("username"); } ``` *注意:此方法仅对POST请求有效* --- ##### 2. 处理GET请求乱码 **方案一**:修改Tomcat配置(推荐) 修改`server.xml`中的Connector配置: ```xml <Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8" <!-- 强制URI解码使用UTF-8 --> useBodyEncodingForURI="true" <!-- 使GET参数使用与POST相同的编码 --> /> ``` **方案二**:代码层手动转码 ```java String param = new String( request.getParameter("param") .getBytes("ISO-8859-1"), // 按服务器默认解码 "UTF-8" // 目标编码 ); ``` --- ##### 3. 统一设置过滤器(最佳实践) 创建EncodingFilter全局处理所有请求: ```java @WebFilter("/*") public class EncodingFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); chain.doFilter(req, resp); } } ``` --- ##### 4. 前端页面配合 确保页面使用UTF-8编码: ```html <!-- HTML5标准写法 --> <meta charset="UTF-8"> <!-- 表单提交方式 --> <form action="/submit" method="post" accept-charset="UTF-8"> ``` --- #### 三、验证流程 1. 使用浏览器开发者工具检查请求头`Content-Type` 2. 通过`System.out.println(param)`输出服务器接收内容 3. 使用Wireshark/Fiddler抓包验证原始数据 --- #### 四、扩展注意事项 - 数据库连接需添加`?useUnicode=true&characterEncoding=UTF-8` - 响应输出流设置:`response.setContentType("text/html;charset=UTF-8")` - JSON传输时设置:`application/json;charset=UTF-8` 通过以上步骤可系统性解决95%的中文乱码问题。如果仍出现乱码,需检查各环节编码一致性(客户端→网络传输→服务器→数据库→响应输出)。
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙 子_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值