Requset和Response中的乱码问题

       在我们的日常开发中,乱码问题,还是比较经常遇到的,有时候是浏览器端提交的数据到后台乱码了,有时候是后台响应的数据到前台浏览器端展现出现乱码了。下面我们将通过几个简单的例子来说明乱码的由来和解决方式。

一、前台提交的数据到后端乱码了

1.前台采用post方式提交,后端乱码

①jsp提交数据页面代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="encode.do" method="post">
        用户名:<input type="text" name="username" /> <input type="submit" value="提交" />
    </form>
</body>
</html>

②后端接受参数的代码

package com.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/encode.do")
public class EncodingServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取前台提交的数据
        String username = request.getParameter("username");
        // 打印输出
        System.out.println(username);
    }
}

③运行结果

当我们从前台输入中文数据的时候,就会出现乱码了"??????"

④乱码原因:jsp页面的<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>说明了页面的编码是UTF-8和<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">这句话告诉浏览器以UTF-8的方式打开我们的jsp页面,当我们在页面的输入框中填写中文表单数据并提交的时候,会先去查询utf-8的码表对应中文在utf-8的编码值,因为tomcat服务器的默认编码是ISO-8859-1,当我们从后端通过request.getParameter("username")去获取参数的时候,就会拿着我们刚才utf-8的编码值去ISO-8859-1查询对应的字符,而在ISO-8859-1的码表没有这个编码指,所以就出现了???乱码了。

⑤解决乱码的方式:因为浏览器提交的数据是以utf-8进行编码的,所以我们可以通过改变request对象查询的码表改成和浏览器端的编码一致即可解决乱码问题。具体代码如下所示

package com.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/encode.do")
public class EncodingServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置request的编码和前台页面的编码保持一致utf-8
        request.setCharacterEncoding("utf-8");
        // 获取前台提交的数据
        String username = request.getParameter("username");
        // 打印输出
        System.out.println(username);
    }
}

2.前台采用get方式提交,后端乱码(哪怕修改了request的编码和页面的编码保持一致,也不行

①jsp提交数据页面代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="encode.do" method="get">
        用户名:<input type="text" name="username" /> <input type="submit" value="提交" />
    </form>
</body>
</html>

②后端接受参数的代码

package com.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/encode.do")
public class EncodingServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取前台提交的数据
        String username = request.getParameter("username");
        // 打印输出
        System.out.println(username);
    }

}

③运行结果

当我们从前台输入中文数据的时候,就会出现乱码了"??????"

④乱码原因:jsp页面的<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>说明了页面的编码是UTF-8和<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">这句话告诉浏览器以UTF-8的方式打开我们的jsp页面,当我们在页面的输入框中填写中文表单数据并提交的时候,会先去查询utf-8的码表对应中文在utf-8的编码值,因为tomcat服务器的默认编码是ISO-8859-1,当我们从后端通过request.getParameter("username")去获取参数的时候,就会拿着我们刚才utf-8的编码值去ISO-8859-1查询对应的字符,而在ISO-8859-1的码表没有这个编码指,所以就出现了???乱码了。

⑤解决乱码的方式:因为浏览器提交的数据是以utf-8进行编码的,但是我们通过改变request对象查询的码表改成和浏览器端的编码一致依然不能解决乱码问题,这时候我们可以修改tomcat的server.xml中的编码保持和前端页面保持一致即可,就是在Connector标签上加上URIEncoding="前端页面的编码",代码如下:

 <Connector connectionTimeout="20000" port="8080" URIEncoding="UTF-8"  protocol="HTTP/1.1" redirectPort="8443"/>

3.一个既能够解决get方式乱码,又能解决post方式乱码的方式如下,就是反向编码,获取原来的编码值,在用这个编码值查询正确的码表即可获取正确的字符了。

package com.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/encode.do")
public class EncodingServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取前台提交的数据
        String username = request.getParameter("username");
        //对获取的数据进行方向编码,获取原来的编码值,在查询新码表
        username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
        // 打印输出
        System.out.println(username);
    }
}

4.总结:

①对于get的方式的乱码我们一般都是通过修改tomcat的server.xml的方式来进行处理的。

②对于post方式的乱码,我们一般都是采用request.setCharacterEncoding的方式来处理的。

二、后端提交的数据到前端乱码了

1.jsp提交请求页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="/JavaWebDemo/encode.do" method="post">
        <input type="submit" value="get提交" />
    </form>
        <form action="/JavaWebDemo/encode.do" method="get">
        <input type="submit" value="post提交" />
    </form>
</body>
</html>

2.后端响应,并返回数据代码

package com.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/encode.do")
public class EncodingServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 返回数据
        response.getWriter().print("还是放松放松放松放松");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 返回数据
        response.getWriter().print("还是放松放松放松放松");
    }

}

3.运行结果

结果返现,返回的数据乱码了。

4.乱码问题分析:我们后端返回数据是通过response对象获取相关的流对象,然后将数据返回,但是后端的数据采用的编码方式ISO-8859-1,而前台页面我们没有指定使用什么编码,他默认会采用本地机器的浏览器使用编码去打开,自然会报错。

5乱码结果方法:我们可以设置http的返回头的contenttype的内容来解决乱码问题,具体事例代码如下:

package com.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/encode.do")
public class EncodingServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println(response.getCharacterEncoding());
        response.setContentType("text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        // 返回数据
        response.getWriter().print("还是放松放松放松放松");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setHeader("CONTENTTYPE", "text/html;charset=gbk");
        response.setCharacterEncoding("gbk");
        // 返回数据
        response.getWriter().print("还是放松放松放松放松");
    }

}

至此,关于servlet中request和response中的乱码问题已经解决了,有不足的地方,希望大家多多提意见!

原文地址:https://www.cnblogs.com/nanyangke-cjz/p/7142067.html