目录
一、当Request请求字母时,输出正常
二、当Request请求参数为汉字时
三、使用伪代码了解乱码的形成
URL编码
四、Request请求参数中文乱码-Post请求解决方案
五、Request请求参数中文乱码-Get请求解决方案
前言:Tomcat在7以及更低版本时,解析中文的字符集默认为ISO-8859-1,并且是在底层写死的,所以浏览器发送Get请求或者时Post请求时,字符集格式不匹配,从而引发中文乱码。但是Tomcat更新到8版本后,默认字符集就更换为了UTF-8。
一、当Request请求字母时,输出正常
package com.huanle.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.IOException;
/**
* @author 欢了
* @version 1.0
*/
@WebServlet("/req3")
public class RequestDemo3 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("==========字母情况下===========");
String username = request.getParameter("username");
System.out.println(username);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
启动Tomcat 在输入框 姓名里 输入字母abc
点击提交跳转到上面代码开始执行
控制台打印abc
一切正常
二、当Request请求参数为汉字时
启动Tomcat 在姓名框中输入中文 张三
跳转页面
看控制台的输出
输入的张三在控制台里呈现的就是乱码
三、使用伪代码了解乱码的形成
解决乱码问题之前,首先我们要了解乱码的形成。
我们写一个测试类,里面用到了URL编码,我们先了解一下;
URL编码
1. 将字符串按照编码格式转为二进制
2.每个字节转为2个16进制数,并在前面加上 %
例如 张三
假设浏览器给Tomcat发送的字符集格式为UTF-8,即编码格式为UTF-8;Tomcat也用UTF-8来接收,即解码格式也为UTF-8,那么就可以正常的接收到 "张三" 。
但是由于tomcat的默认解码是ISO-8859-1,并且还是底层是写死的,就只能走下面示例tomcatDecode对象(乱码)。
tomcatDecode对象直接转UTF-8虽然会出问题,但是底层的二进制是不会变的,我们就有了一个思路:
先将tomcatDecode的解码%E5%BC%A0%E4%B8%89 转为字节数组(-27 -68 -96 -28 -72 -119)
再将字节数组转为字符串。
package com.huanle.web;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* @author 欢了
* @version 1.0
*
* 演示浏览器的URL编码 和 tomcat的URL解码
* 以及解决默认tomcat字符集中文乱码
*/
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);//%E5%BC%A0%E4%B8%89
//URL解码
String decode = URLDecoder.decode(encode, "UTF-8");
System.out.println(decode);//张三
//但是tomcat的默认解码是ISO-8859-1,并且底层是写死的
String tomcatDecode = URLDecoder.decode(encode, "ISO-8859-1");
System.out.println(tomcatDecode);
/**
* 解决get请求的中文乱码
* 将tomcat的乱码,先用tomcat默认的字符集ISO-8859-1转为字节数组 编码
* 再将字节数组转为字符串 解码
* */
byte[] bytes = tomcatDecode.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);//张三
}
}
最终的结果如下:
四、Request请求参数中文乱码-Post请求解决方案
讲完上面的案例,大家也就知道为什么中文会出现乱码了,我们就在代码中解决
因为Post是通过流的getReader()方法来传输数据,只需要改变流的编码格式为utf-8即可
我们需要用到一个方法 setCharacterEncoding(""); //这里的参数是编码格式
启动Tomcat 姓名为 张三
跳转页面后没有显示请求参数 ,所以是Post请求
package com.huanle.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.IOException;
/**
* @author 欢了
* @version 1.0
*
* 中文乱码解决方案
*/
@WebServlet("/req4")
public class RequestDemo4 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.先解决乱码问题Post,因为Post是通过流getReader()方法 传输数据,改变流的编码格式为utf-8
request.setCharacterEncoding("utf-8");
//2.获取username
System.out.println("==========获取username=========");
String username = request.getParameter("username");
System.out.println("解决后" + username);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
输出正常! 解决~
五、Request请求参数中文乱码-Get请求解决方案
get请求就很像我们举得测试类里的例子
先将乱码的数据转成字节数组
再将字节数组转成字符串
package com.huanle.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.IOException;
/**
* @author 欢了
* @version 1.0
*
* 中文乱码解决方案
*/
@WebServlet("/req4")
public class RequestDemo5 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取username
System.out.println("==========获取username=========");
String username = request.getParameter("username");
System.out.println("解决前:" + username);
//2.解决乱码问题Get Get是通过getQueryString
// 乱码原因,tomcat进行URL解码的时候用的是ISO-8859-1的字符集,和页面字符集不匹配
// 解决方案:
// 2.1 先将乱码的数据转成字节数组
// 2.2 再将字节数组转成字符串
byte[] bytes = username.getBytes("ISO-8859-1");
String s = new String(bytes, "UTF-8");
System.out.println("解决后:" + s);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
启动Tomcat
跳转页面,有显示参数,表明是Get请求
输出正常!解决~