解決Request獲取請求數(shù)據(jù)中文亂碼問題
Tomcat在7以及更低版本時,解析中文的字符集默認(rèn)為ISO-8859-1,并且是在底層寫死的,所以瀏覽器發(fā)送Get請求或者時Post請求時,字符集格式不匹配,從而引發(fā)中文亂碼。
但是Tomcat更新到8版本后,默認(rèn)字符集就更換為了UTF-8。
一、當(dāng)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

點(diǎn)擊提交跳轉(zhuǎn)到上面代碼開始執(zhí)行

控制臺打印abc

一切正常
二、當(dāng)Request請求參數(shù)為漢字時
啟動Tomcat 在姓名框中輸入中文 張三

跳轉(zhuǎn)頁面

看控制臺的輸出

輸入的張三在控制臺里呈現(xiàn)的就是亂碼
三、使用偽代碼了解亂碼的形成
解決亂碼問題之前,首先我們要了解亂碼的形成。
我們寫一個測試類,里面用到了URL編碼,我們先了解一下;
URL編碼
- 1. 將字符串按照編碼格式轉(zhuǎn)為二進(jìn)制
- 2.每個字節(jié)轉(zhuǎn)為2個16進(jìn)制數(shù),并在前面加上 %
例如 張三

假設(shè)瀏覽器給Tomcat發(fā)送的字符集格式為UTF-8,即編碼格式為UTF-8;Tomcat也用UTF-8來接收,即解碼格式也為UTF-8,那么就可以正常的接收到 "張三" 。
但是由于tomcat的默認(rèn)解碼是ISO-8859-1,并且還是底層是寫死的,就只能走下面示例tomcatDecode對象(亂碼)。
tomcatDecode對象直接轉(zhuǎn)UTF-8雖然會出問題,但是底層的二進(jìn)制是不會變的,我們就有了一個思路:
先將tomcatDecode的解碼%E5%BC%A0%E4%B8%89 轉(zhuǎn)為字節(jié)數(shù)組(-27 -68 -96 -28 -72 -119)
再將字節(jié)數(shù)組轉(zhuǎn)為字符串。
package com.huanle.web;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* @author 歡了
* @version 1.0
*
* 演示瀏覽器的URL編碼 和 tomcat的URL解碼
* 以及解決默認(rèn)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的默認(rèn)解碼是ISO-8859-1,并且底層是寫死的
String tomcatDecode = URLDecoder.decode(encode, "ISO-8859-1");
System.out.println(tomcatDecode);
/**
* 解決get請求的中文亂碼
* 將tomcat的亂碼,先用tomcat默認(rèn)的字符集ISO-8859-1轉(zhuǎn)為字節(jié)數(shù)組 編碼
* 再將字節(jié)數(shù)組轉(zhuǎn)為字符串 解碼
* */
byte[] bytes = tomcatDecode.getBytes("ISO-8859-1");
//可以先遍歷看一下
for (byte b : bytes) {
System.out.print(b + " ");
}//-27 -68 -96 -28 -72 -119
//換行
System.out.println();
//將這些十進(jìn)制轉(zhuǎn)為字符串
String s = new String(bytes, "UTF-8");
System.out.println(s);//張三
}
}最終的結(jié)果如下:

四、Request請求參數(shù)中文亂碼-Post請求解決方案
講完上面的案例,大家也就知道為什么中文會出現(xiàn)亂碼了,我們就在代碼中解決
因為Post是通過流的getReader()方法來傳輸數(shù)據(jù),只需要改變流的編碼格式為utf-8即可
我們需要用到一個方法 setCharacterEncoding(""); //這里的參數(shù)是編碼格式
啟動Tomcat 姓名為 張三

跳轉(zhuǎn)頁面后沒有顯示請求參數(shù) ,所以是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()方法 傳輸數(shù)據(jù),改變流的編碼格式為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請求參數(shù)中文亂碼-Get請求解決方案
get請求就很像我們舉得測試類里的例子
先將亂碼的數(shù)據(jù)轉(zhuǎn)成字節(jié)數(shù)組
再將字節(jié)數(shù)組轉(zhuǎn)成字符串
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進(jìn)行URL解碼的時候用的是ISO-8859-1的字符集,和頁面字符集不匹配
// 解決方案:
// 2.1 先將亂碼的數(shù)據(jù)轉(zhuǎn)成字節(jié)數(shù)組
// 2.2 再將字節(jié)數(shù)組轉(zhuǎn)成字符串
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

跳轉(zhuǎn)頁面,有顯示參數(shù),表明是Get請求


輸出正常!解決~
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java通過數(shù)據(jù)庫表生成實體類詳細(xì)過程
這篇文章主要介紹了Java通過數(shù)據(jù)庫表生成實體類,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-02-02
springBoot?之spring.factories擴(kuò)展機(jī)制示例解析
這篇文章主要為大家介紹了springBoot?之spring.factories擴(kuò)展機(jī)制示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
java遠(yuǎn)程連接調(diào)用Rabbitmq的實例代碼
本篇文章主要介紹了java遠(yuǎn)程連接調(diào)用Rabbitmq的實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07
Mybatis數(shù)據(jù)批量插入如何實現(xiàn)
這篇文章主要介紹了Mybatis數(shù)據(jù)批量插入如何實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07
spring-boot-autoconfigure模塊用法詳解
autoconfigure就是自動配置的意思,spring-boot通過spring-boot-autoconfigure體現(xiàn)了"約定優(yōu)于配置"這一設(shè)計原則,而spring-boot-autoconfigure主要用到了spring.factories和幾個常用的注解條件來實現(xiàn)自動配置,思路很清晰也很簡單,感興趣的朋友跟隨小編一起看看吧2022-11-11
Java并發(fā)編程之Semaphore(信號量)詳解及實例
這篇文章主要介紹了Java并發(fā)編程之Semaphore(信號量)詳解及實例的相關(guān)資料,需要的朋友可以參考下2017-06-06

