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

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

控制臺(tái)打印abc

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

跳轉(zhuǎn)頁(yè)面

看控制臺(tái)的輸出

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

假設(shè)瀏覽器給Tomcat發(fā)送的字符集格式為UTF-8,即編碼格式為UTF-8;Tomcat也用UTF-8來(lái)接收,即解碼格式也為UTF-8,那么就可以正常的接收到 "張三" 。
但是由于tomcat的默認(rèn)解碼是ISO-8859-1,并且還是底層是寫(xiě)死的,就只能走下面示例tomcatDecode對(duì)象(亂碼)。
tomcatDecode對(duì)象直接轉(zhuǎn)UTF-8雖然會(huì)出問(wèn)題,但是底層的二進(jìn)制是不會(huì)變的,我們就有了一個(gè)思路:
先將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,并且底層是寫(xiě)死的
String tomcatDecode = URLDecoder.decode(encode, "ISO-8859-1");
System.out.println(tomcatDecode);
/**
* 解決get請(qǐng)求的中文亂碼
* 將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請(qǐng)求參數(shù)中文亂碼-Post請(qǐng)求解決方案
講完上面的案例,大家也就知道為什么中文會(huì)出現(xiàn)亂碼了,我們就在代碼中解決
因?yàn)镻ost是通過(guò)流的getReader()方法來(lái)傳輸數(shù)據(jù),只需要改變流的編碼格式為utf-8即可
我們需要用到一個(gè)方法 setCharacterEncoding(""); //這里的參數(shù)是編碼格式
啟動(dòng)Tomcat 姓名為 張三

跳轉(zhuǎn)頁(yè)面后沒(méi)有顯示請(qǐng)求參數(shù) ,所以是Post請(qǐng)求

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.先解決亂碼問(wèn)題Post,因?yàn)镻ost是通過(guò)流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請(qǐng)求參數(shù)中文亂碼-Get請(qǐng)求解決方案
get請(qǐng)求就很像我們舉得測(cè)試類里的例子
先將亂碼的數(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.解決亂碼問(wèn)題Get Get是通過(guò)getQueryString
// 亂碼原因,tomcat進(jìn)行URL解碼的時(shí)候用的是ISO-8859-1的字符集,和頁(yè)面字符集不匹配
// 解決方案:
// 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);
}
}啟動(dòng)Tomcat

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


輸出正常!解決~
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Security與SaToken的對(duì)比與優(yōu)缺點(diǎn)分析
這篇文章主要介紹了Spring Security與SaToken的對(duì)比與優(yōu)缺點(diǎn)分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-05-05
詳解在spring中使用JdbcTemplate操作數(shù)據(jù)庫(kù)的幾種方式
這篇文章主要介紹了詳解在spring中使用JdbcTemplate操作數(shù)據(jù)庫(kù)的幾種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
SpringBoot實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳功能詳解
在處理大文件傳輸或網(wǎng)絡(luò)不穩(wěn)定的情況下,文件斷點(diǎn)續(xù)傳功能顯得尤為重要,本文將詳細(xì)介紹如何使用Spring Boot實(shí)現(xiàn)文件的斷點(diǎn)續(xù)傳功能,需要的可以了解下2025-04-04
Java中使用While語(yǔ)句自增運(yùn)算遍歷數(shù)組典型實(shí)例
這篇文章主要介紹了Java中使用While語(yǔ)句自增運(yùn)算遍歷數(shù)組典型實(shí)例,本文直接給出實(shí)例代碼,并對(duì)每一句代碼都注解了詳細(xì)注釋,需要的朋友可以參考下2015-06-06
SpringCloud注冊(cè)中心部署Eureka流程詳解
Eureka是Netflix開(kāi)發(fā)的服務(wù)發(fā)現(xiàn)框架,本身是一個(gè)基于REST的服務(wù),主要用于定位運(yùn)行在AWS域中的中間層服務(wù),以達(dá)到負(fù)載均衡和中間層服務(wù)故障轉(zhuǎn)移的目的2022-11-11
Java動(dòng)態(tài)數(shù)組ArrayList實(shí)現(xiàn)動(dòng)態(tài)原理
ArrayList是一種動(dòng)態(tài)數(shù)組,它可以在運(yùn)行時(shí)自動(dòng)調(diào)整大小以適應(yīng)元素的添加和刪除,在Java中,你可以使用ArrayList類來(lái)實(shí)現(xiàn)動(dòng)態(tài)數(shù)組,本文將給大家介紹一下ArrayList動(dòng)態(tài)數(shù)組,是怎么實(shí)現(xiàn)動(dòng)態(tài)的2023-08-08
Java讀取網(wǎng)頁(yè)內(nèi)容并下載圖片的實(shí)例
這篇文章主要介紹了Java讀取網(wǎng)頁(yè)內(nèi)容并下載圖片的實(shí)例的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-09-09

