JavaWeb 亂碼問題終極解決方案!

2021-02-23 江南一點雨

經常有讀者在公眾號上問 JavaWeb 亂碼的問題,昨天又有一個小夥伴問及此事,其實這個問題很簡單,但是想要說清楚卻並不容易,因為每個人亂碼的原因都不一樣,給每位小夥伴都把亂碼的原因講一遍也挺費時間的,因此,松哥今天決定寫一篇文章,和大夥好好捋捋 JavaWeb 中的亂碼問題。

對於一些老司機而言,其實並不太容易遇到亂碼問題,但是對於一些新手來說,亂碼幾乎是家常便飯,而且每當亂碼時,網上搜了一大堆解決方案,發現自己的問題還是沒能解決,其實這就是平時研究代碼不求甚解導致的,亂碼問題,也要去分析,然後才能對症下藥,才能藥到病除。

整體思路

首先出現亂碼之後,要先去確認亂碼的地方,當一個網頁上出現亂碼,有可能是瀏覽器顯示問題,也有可能是 Java 編碼問題,也有可能資料庫中的數據本身就是亂碼的,所以我們要做的第一件事就是確認亂碼發生的位置,縮小 bug 範圍,通過列印日誌或者 debug 首先去確認亂碼發生的位置,然後再去進一步解決,一般來說,亂碼的原因大致上可以分為兩類:

請求亂碼,可能是因為參數放在 URL 地址中亂碼,也有可能是參數放在請求體中亂碼,不同傳參方案也對應了不同的亂碼解決方案。如果是響應亂碼,那麼原因就會比較多了,一般來說,有如下幾種可能的原因:

資料庫本身亂碼

數據在 Java 代碼中亂碼

數據在瀏覽器顯示的時候亂碼

數據在從 Java 應用傳到資料庫的過程中亂碼

對於不同的亂碼原因,會有不同的解決方案,對症下藥,才能藥到病除,所以當出現亂碼時,大家要做的第一件事就是分析亂碼發生的原因,找到原因了,才能找到解決方案。

基本原則

發生亂碼是因為各自編碼不同導致的,所以,大家首先要有一個良好的開發習慣,項目編碼,文件編碼都要統一起來,松哥有個同事就因為 Freemarker 亂碼,找了半天沒找到原因,後來在松哥建議下修改了項目編碼,亂碼問題才解決了,一般來說,公司制度稍微成熟一些,都會對項目編碼,文件編碼有硬性規定的。在Eclipse 中,設置項目編碼方式如下(工程的編碼要提前設置,如果項目已經開發一半再去設置,已有的中文就會亂碼):

Window->Preferences->General

然後對於 JSP 文件也需要提前設置好編碼方式,如下:

這是在 Eclipse 中設置文件編碼,如果是在 IntelliJ IDEA中,則不需要設置JSP文件編碼,因為默認就是 UTF-8,只需要提前設置下工程編碼即可:

除了開發工具的編碼,資料庫的編碼也要統一,一般來說,主要是設置一下資料庫的編碼和數據表的編碼,如下:

設置資料庫編碼:

CREATE DATABASE `vhr` DEFAULT CHARACTER SET utf8;

設置數據表編碼:

DROP TABLE IF EXISTS `adjustsalary`;

CREATE TABLE `adjustsalary` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`eid` int(11) DEFAULT NULL,

PRIMARY KEY (`id`),

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

這些是準備工作,這些工作做好了,還是有可能會遇到亂碼問題,接下來我們就具體問題具體分析。

請求亂碼

請求亂碼,就是說數據在瀏覽器中顯示是正常的,但是傳到 Java 後端之後,就亂碼了,這種亂碼一般來說,分為兩種:

參數放在 URL 地址中導致的亂碼

參數放在請求體中導致的亂碼

兩種亂碼原因,對應了兩種不同的解決方案。分別來看。

URL 地址中的參數亂碼

這種亂碼主要發生在 GET 請求中,因為在 GET 請求中我們一般通過 URL 來傳遞參數,這個問題可以在代碼中解決,但是太過於麻煩,因此一般我們直接在Tomcat配置中解決,修改 Tomcat的conf/server.xml 文件,修改 URL 編碼格式,如下:

這樣就可以搞定 URL 地址中的參數亂碼。

請求體中的參數亂碼

請求體中的參數亂碼,我們可以在解析參數之前通過設置 HttpServletRequest 的編碼來解決,如下:

request.setCharacterEncoding("UTF-8");

但是一樣也太過於麻煩,所以如果是普通的 Servlet/JSP 項目,我們就可以直接定義一個過濾器來處理,如下:

public class EncodingFilter implements Filter {

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

request.setCharacterEncoding("UTF-8");

chain.doFilter(request, response);

}

}

過濾器配置:

<filter>

<filter-name>encodingFilter</filter-name>

<filter-class>org.sang.filter.EncodingFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>encodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

在工程編碼和JSP/HTML編碼都沒問題的情況下,請求亂碼基本上就是這兩種情況。

響應亂碼

如果在瀏覽器上加載頁面看到了亂碼,大家首先要確認在從服務端往瀏覽器寫數據的前一刻,這個數據還沒有亂碼(即資料庫中查詢出來的數據是OK的,沒有發生亂碼的問題),那麼對於這種亂碼,我們只需要設置響應數據的 ContentType 就可以了,如下:

response.setContentType("text/html;charset=UTF-8");

如果從資料庫中查詢出來的數據就是亂碼的,那麼就需要去確認資料庫中的編碼是否 OK 。

框架處理

前面提到的方案,都是在 Servlet/JSP 項目中我們可以採用的方案,在 SSM 框架中當然也可以使用,但是,SpringMVC 框架本身也提供了一個過濾器,我們可以借用這個過濾器更加高效的解決響應亂碼問題,如下:

<filter>

<filter-name>encoding</filter-name>

<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>UTF-8</param-value>

</init-param>

<init-param>

<param-name>forceRequestEncoding</param-name>

<param-value>true</param-value>

</init-param>

<init-param>

<param-name>forceResponseEncoding</param-name>

<param-value>true</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>encoding</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

當然,上面這段配置並不能代替 Tomcat 中 conf/server.xml 中的編碼配置,如果是在 Spring Boot 中,配置可以更加簡單,只需要在 application.properties 中添加如下配置即可:

server.tomcat.uri-encoding=UTF-8

spring.http.encoding.force-request=true

spring.http.encoding.force-response=true

其他亂碼

其他亂碼主要是指使用一些第三方框架導致的亂碼,例如使用 Alibaba 的 fastjson,開發者就需要在配置 HttpMessageConverter 時指定編碼格式,否則就有可能出現亂碼,這種第三方框架的亂碼松哥沒法窮舉,大夥在使用時需要注意看官方文檔,fastjson 的 HttpMessageConverter 配置如下:

@Bean

FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {

FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();

FastJsonConfig config = new FastJsonConfig();

config.setCharset(Charset.forName("UTF-8"));

converter.setFastJsonConfig(config);

converter.setDefaultCharset(Charset.forName("UTF-8"));

return converter;

}

一個隱蔽的亂碼

除了前面介紹的這幾種亂碼之外,還有一個比較隱蔽的亂碼,容易被很多初學者忽略的地方,就是數據在從 Java 應用傳遞到 MySQL 的過程中,發生了亂碼,這種問題一般在 Windows 上不易發生,如果資料庫裝在 Linux 上,則這個問題就很容易發生,數據在代碼中命名沒有亂碼,存到 MySQL 上就亂碼了,但是如果直接使用 Navicat 等工具往 MySQL 上存儲數據,又不會亂碼,或者 MySQL 中數據沒有亂碼,但是用 Java 查詢出來就亂碼了,這種都是數據在 應用 和 資料庫 之間傳遞時發生了亂碼,解決方式很簡單,在資料庫連接地址上指定編碼即可,如下:

db.url=jdbc:mysql:///yuetong?useUnicode=true&characterEncoding=UTF-8

大致就這些,還有一些非常偶爾的情況可能會用到 @RequestMapping 註解中的 produces 屬性,在這裡指定數據類型即可。

好了,差不多就這些,下次有人問你為啥我的又亂碼了,直接把這篇文章甩給他。大夥有什麼解決亂碼的獨門密器也可以一起來討論。

關注公眾號,後臺回復 Java ,有松哥私藏多年的乾貨哦!

相關焦點

  • 解決idea控制臺中文亂碼問題
    可是有時候會遇到中文亂碼問題。本文將介紹大家,怎麼解決idea的控制臺中文亂碼情況。請看亂碼信息:程序報錯了。可是控制臺又亂碼了,怎麼解決呢?一:設置所有文件都是UTF-8編碼。
  • 字符集及其存儲方式(解決亂碼問題)
    閱讀大概需要4分鐘在我們進行文本挖掘或處理文檔時,都要面臨一個最最基本的問題->就是解決亂碼問題。
  • SOLIDWORKS工程圖轉DWG字體亂碼的解決方案
    就像昨天提到的,有時候SOLIDWORKS工程圖轉換DWG格式不可避免,那麼除了圖層之外,還有就是字體亂碼的問題比較多了。其實說句實話,兩個軟體使用的不是同一個字體,在轉換過程中或多或少都會有一些問題存在的,SOLIDWORKS使用的是Windows字體,而CAD使用的是線性字體,所以在轉換過程中,即使沒有亂碼,有時字體也不能對齊稍微有些錯亂,這個時候如果字體庫比較豐富的,兩個軟體的對齊方式也一樣的話,就會比較好,這些都是很好解決的,今天就說如果出現亂碼的情況怎麼解決?
  • 如何解決MapInfo打開文字亂碼的問題
    在使用MapInfo的過程中有時候會遇到這樣的情況,由於文字中有韓語、日語或者阿拉伯語等文字的時候會顯示為亂碼或者問號,這主要是文字編碼的問題,這裡以shp格式的數據轉換為tab格式為例,介紹一下解決的方法。
  • 用ua命令來解決文件亂碼問題
    比如在上篇推文《數據整理:歷任基金經理變更數據》中,一開始Stata讀入一個txt文件,裡面所有的中文全部變成亂碼了。如下圖讀入前:讀入後 :在上篇推文中,我們用Stata中的import delimited的encoding 選項來解決亂碼問題。
  • 解決Redis 中文亂碼問題
    今天幫大家解決一個問題,昨晚雞排妹做Redis緩存的時候出現亂碼的問題。最後去Redis文檔看看問題,是序列化問題。所以我想到了一個辦法。
  • iPad郵件亂碼怎麼辦_iPad郵件亂碼解決教程
    iPad郵件亂碼怎麼辦_iPad郵件亂碼解決教程 2014-07-31 10:38 | 作者:SORA | 來源:265G QQ群號:624022706
  • 自己動手 教你解決AKAIO金手指亂碼問題
    內容分享:jy02351812  AK自製內核AKAIO因為更新快,功能多受到不少AK燒錄卡用戶的青睞,但是由於內核的編碼問題,導致AK本身的金手指包括兼容的R4金手指文件在AKAIO內核上顯示亂碼。
  • 如何解決PL/SQL中文亂碼問題
    打開PL/SQL執行sql語句,中文顯示亂碼??? 如何解決上述問題,辦法如下: 1)輸入sql語句select userenv('language') from dual 按下F8執行語句,查看資料庫字符集; 2)輸入sql語句select * from V$NLS_PARAMETERS查看本地字符集;
  • 我這樣解決TXT亂碼
    今天下載了幾個TXT格式的小說,都是亂碼。於是,找度娘解決問題。
  • 微信《海盜來了》亂碼怎麼辦 出現亂碼解決辦法
    導 讀 最近在微信上有一款叫海盜來了的小程序遊戲很火,有不少人都蜂擁者去玩,但是有不少玩家在遊戲中遇到了亂碼的情況
  • 快速解決 matplotlib 中文亂碼問題
    最近做了一個雲盤性能對比,用 matplotlib 繪製了一張圖,但是碰到了中文亂碼問題。簡單搜索之後,發現有人總結出了比較好的方案,親測可行。推薦給大家。作者:nphard 原文連結:http://nphard.me/2016/03/27/matplotlib-cn一個中文亂碼問題,讓我搞的好苦,總結一下。
  • escape解決AJAX中文亂碼的簡單方法
    首頁 > 語言 > 關鍵詞 > asp最新資訊 > 正文 escape解決AJAX中文亂碼的簡單方法
  • word打開是亂碼的5種解決方法
    內容提要:本文介紹word打開是亂碼的五種解決方法,比如刪除格式、轉換格式、打開並修復、提取文字等等來解決Word亂碼問題。 時不時都會遇到群裡朋友問到word打開是亂碼,該如何處理。word打開是亂碼有可能是文件格式出現問題,也有可能遭病毒,或者是文檔被破壞等等原因。
  • SPSS基礎:【09】數據文件亂碼解決辦法
    有時候,我們打開從其他人那裡或者網上下載的spss格式的數據文件會出現亂碼。為什麼會出現亂碼呢?如何解決亂碼問題呢?一、為什麼會出現亂碼?數據文件在存儲時,一般都有對應的編碼方式,我將它稱為存儲編碼。如果存儲編碼和打開編碼不一致,那麼就有可能出現亂碼。為什麼說有可能,而不是一定會亂碼呢?這是因為所謂的編碼方式,其實是對我們常見的文字的編碼,就是把英文,數字,漢字或者其它文字編碼成一系列的代碼,便於計算機存儲和處理。
  • 信長之野望14創造PC版亂碼 WIN7系統亂碼解決方法
    信長之野望14PC版亂碼問題,巴士小編也同樣遇到。在此,小編和大家分享一下解決方案。  》信長之野望14PC測試版下載  信長之野望14 亂碼問題:  一、小編下載的是信長之野望14PC測試版,進入遊戲後出現亂碼,人物名稱、對話完全無法直視。  二、電腦系統環境為WIN7。
  • 《廢品機械師》中文亂碼怎麼辦?中文亂碼修複方法介紹
    廢品機械師中文亂碼怎麼辦?
  • Windows和Ubuntu Linux安裝VScode解決打開文件時中文亂碼問題
    我們本文就介紹下Windows和Ubuntu這樣的Linux兩個作業系統下安裝VScode編輯器並解決打開代碼文件的時候其中中文顯示亂碼的問題。當然Windows版本的VScode安裝很簡單,我們很多人都是從Windows過來的,安裝文件無非是一路下一步而已。安裝VScode也差不多,我們下載EXE文件,雙擊安裝就行了。
  • PDF轉word亂碼怎麼辦?這樣輕鬆解決!
    PDF轉word亂碼怎麼辦?我們經常需要將PDF文件轉換成word格式,因為這樣就可以對pdf文件進行編輯啦。但是有不少朋友在將pdf轉word的時候會出現亂碼的問題,你頭疼不已!別擔心,下面小編要告訴大家的就是如何高效率地將PDF文件轉換成Word格式,拒絕亂碼!
  • Java中文亂碼解決之道:認識字符集
    ,每次遇到中文亂碼LZ要麼是按照以前的經驗修改,要麼則是baidu.com來解決問題。閱讀許多關於中文亂碼的解決辦法的博文後,發現對於該問題我們都(更加包括我自己)沒有一個清晰明了的認識,於是LZ想通過這系列博文(估計只有幾篇)來徹底分析、解決java中文亂碼問題,如有錯誤之處望各位同仁指出!