Get 与Post 请求数据乱码处理

版权声明:欢迎转载,若转载请给出本文链接 https://blog.csdn.net/niaonao/article/details/82901508
Get 与Post 请求方式下中文数据的响应处理

1. 前言

某交流群
Just now

提问者:
    Get 请求,中文乱码怎么处理?
热心人:
    对request 设置编码格式为UTF-8 能解决。
    就是下面这样
    request.setCharacterEncoding(“UTF-8”);
    response.setCharacterEncoding(“UTF-8”);

Soon

提问者:
    这样不行,获取数据还是乱码的。

    WTF,N 先生心想着,之前就是靠着上面那两行代码行(keng)走(meng)天(guai)下(pian)的。不行吗?我得试试。

2. 模拟Get/Post 请求与响应

2.1 新建一个Servlet 测试编码转换

    新建一个Java Web Project,在src 下新建package 命名为pers.niaonao.servlet,在此包新建Servlet 命名为GetPostServlet,用作处理前台模拟的请求。配置GetPostServlet 到项目配置文件web.xml。编写index.jsp 用作前端页面模拟发送Get/Post 请求。
2.1.1 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>GetPostServlet</servlet-name>
        <servlet-class>pers.niaonao.servlet.GetPostServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>GetPostServlet</servlet-name>
        <url-pattern>/GetPostServlet</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

2.2 新建一个JSP 模拟请求

2.2.1 index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
</head>
<body>
<hr>
模拟Get 请求
<form action="GetPostServlet" method="get">
    账户:<input type="text" name="name"/><br>
    密码:<input type="password" name="password"/><br>
    <input type="submit" value="提交Get 请求"/>
</form>
<hr>
模拟Post 请求
<form action="GetPostServlet" method="post">
    账户:<input type="text" name="name"/><br>
    密码:<input type="password" name="password"/><br>
    <input type="submit" value="提交Post 请求"/>
</form>
</body>
</html>

    页面请求数据有两个字段name 和password,使name 传递中文数据,password 为英文字母或阿拉伯数字等。
    后台响应前台发出的请求,并获取请求携带的数据name、password,做编码转换,使能正常获取中文数据。
    下面是Servlet 的处理。
2.2.2 GetPostServlet.java

package pers.niaonao.servlet;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class GetPostServlet extends HttpServlet {

    public final String UTF_8 = "UTF-8";
    public final String ISO_8859_1 = "ISO-8859-1";

    /**
     * 字符串编码转换方法
     * @param str 字符串
     * @param sourceCharset 源编码
     * @param targetCharset 目标编码
     * @return
     * @throws UnsupportedEncodingException
     */
    public String changeCharset(String str, String sourceCharset, String targetCharset) throws UnsupportedEncodingException {
        if (str == null) {
            return null;
        }
        //用旧的字符编码解码字符串。解码可能会出现异常。
        byte[] bs = str.getBytes(sourceCharset);
        //用新的字符编码生成字符串
        return new String(bs, targetCharset);
    }

    /**
     * Get 请求响应方法
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        //处理乱码,将通过Get 方式请求数据使用UTF-8 编码解析
        name = changeCharset(name, ISO_8859_1, UTF_8);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<br>$$$ GetServlet 处理后:$$$<br>name: " + name + "<br>password: " + password);

        //设置response
        response.setCharacterEncoding(UTF_8);
        response.setContentType("text/html");
        //输出文本到浏览器
        response.getWriter().printf(stringBuilder.toString());
    }

    /**
     * Post 请求响应方法
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //处理乱码,将通过Post 方式请求数据使用UTF-8 编码解析
        request.setCharacterEncoding(UTF_8);
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<br>$$$ PostServlet 处理后:$$$<br>name: " + name + "<br>password: " + password);

        //设置response
        response.setCharacterEncoding(UTF_8);
        response.setContentType("text/html");
        //输出文本到浏览器
        response.getWriter().printf(stringBuilder.toString());
    }
}

    通过Tomcat 部署一下,运行项目,访问index.jsp,在页面输入数据并请求Servlet 来测试。
    测试结果如下,可以看到两种请求方式下的中文乱码问题都能被解决。
    另外对于Get 请求使用request.setCharacterEncoding(“utf-8”); 确实不能正确处理中文乱码问题。

图2-1、index.jsp 前端页面图
这是一张图片
图2-2、Get 请求响应图
这是一张图片
图2-3、Post 请求响应图
这是一张图片

3. 简单总结

3.1 Get 请求方式

    Tomcat 默认的编码为ISO-8859-1,所以Get 请求乱码问题可以通过修改Tomcat 默认配置编码为UTF-8 来处理。但不建议那样处理。
    从上面的栗子中可以看到,这里仍然是通过代码处理。此处用了一个字符串编码转换的方法。将请求的数据从编码ISO-8859-1 转换为UTF-8 编码下的数据即可。

    /**
     * 字符串编码转换方法
     * @param str 字符串
     * @param sourceCharset 源编码
     * @param targetCharset 目标编码
     * @return
     * @throws UnsupportedEncodingException
     */
    public String changeCharset(String str, String sourceCharset, String targetCharset) throws UnsupportedEncodingException {
        if (str == null) {
            return null;
        }
        //用旧的字符编码解码字符串。解码可能会出现异常。
        byte[] bs = str.getBytes(sourceCharset);
        //用新的字符编码生成字符串
        return new String(bs, targetCharset);
    }

3.2 Post 请求方式

    而Post 则直接对request 对象设置编码格式为UTF-8 即可。相应的响应对象response 也可以设置编码格式为UTF-8。

request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");

更多乱码问题的处理方式

猜你喜欢

转载自blog.csdn.net/niaonao/article/details/82901508