我想只要是在tomcat上做過涉及中文處理的web應用的人幾乎都會遇到這個問題,起初遇到這個問題很是令人頭疼,因為在網(wǎng)上搜了很多解決方案來嘗試,最終得到的中文字符還是變成了火星的泰坦文。原因不是因為網(wǎng)上的方法不對,而是網(wǎng)上的東西都太散了,只能解決一個點的問題,然而當整個系統(tǒng)運行起來的時候還是可能會出現(xiàn)亂碼。那么這究竟是什么原因呢?根據(jù)我的實際應用情況,我系統(tǒng)地總結了一下可能出現(xiàn)亂碼的情況和解決的方法。
先說說亂碼的原理,其實歸根結底就是編碼和解碼時所使用的格式不一致,或者有些編碼格式根本不支持的文字類型。例如一個中文字符串編碼的時候采用的是“UTF-8”,解碼的時候卻使用“ISO-8859-1”,這樣就會產(chǎn)生亂碼。
了解了亂碼產(chǎn)生的基本原理之后,我們來看看一個基于tomcat的web應用到底在哪些環(huán)節(jié)可能出現(xiàn)亂碼問題。通過上面的亂碼原理簡述,我們可以知道,產(chǎn)生亂碼的地方一定都是有涉及到編解碼的地方。從我遇到的亂碼情況來看,出現(xiàn)亂碼的地方大概會有以下幾處:一是客戶端和服務端之間傳輸?shù)膬热莩霈F(xiàn)亂碼;二是服務端和數(shù)據(jù)庫之間出現(xiàn)亂碼;三是服務端和應用服務器之間出現(xiàn)亂碼。其實無論是哪里出現(xiàn)亂碼,解決的方法都是一樣的,就是統(tǒng)一編解碼格式。
對于第一類情況,即客戶端和服務端之間出現(xiàn)亂碼的解決。首先看看服務端向客戶端輸出產(chǎn)生亂碼的情況。我們以jsp為例。一般jsp文件頭部會像下面這樣:
- <%@ page contentType=”text/html; charset= ISO-8859-1″ pageEncoding=” ISO-8859-1″%>
復制代碼
這里是jsp文件默認的字符集和編碼格式都是ISO-8859-1。ISO-8859-1是不支持中文的。所以如果一個jsp文件采用這樣的頭部,而其中又包含有輸出到客戶端的中文的話,那么當客戶端訪問該頁面時,所有的中文都會顯示成亂碼。這種情況是編碼格式原生就不支持中文的情況。另外一種情況就是編碼格式不統(tǒng)一的情況,請看下面這個jsp文件頭部:
- <%@ page contentType=”text/html; charset=ISO-8859-1″ pageEncoding=”UTF-8″%>
復制代碼
在這里我指定了頁面的編碼格式為UTF-8,而contentType中聲明的字符集卻是ISO-8859-1,這樣,在客戶端訪問該頁面的時候,中文依然會是亂碼。所以解決這個問題的要點就是要使用統(tǒng)一的編碼,并且該編碼要支持中文,像下面這樣,中文就可以正確顯示了:
- <%@ page contentType=”text/html; charset=UTF-8″ pageEncoding=”UTF-8″%>
復制代碼
再來講講客戶端向服務端提交數(shù)據(jù)的時候出現(xiàn)亂碼的解決。當我們通過form向服務端提交數(shù)據(jù)的時候,瀏覽器會幫我們把數(shù)據(jù)先進行編碼后再提交,我們可以通過以下方式來指定瀏覽器如何進行編碼,在html文件中加上如下這句話:
- <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
復制代碼
這里就指定了提交到服務端的數(shù)據(jù)采用UTF-8編碼,當然這里只是指定了提交的數(shù)據(jù)編碼格式,還需要在服務端對接受到的請求做同樣的字符集設置才行,如下:
- request.setCharacterEncoding(”UTF-8″);
復制代碼
這樣,服務端接受到請求后取出來的參數(shù)就能正確解碼成中文。
第二種情況就是服務端和數(shù)據(jù)庫之間出現(xiàn)的亂碼。以mysql為例,一般我們配置數(shù)據(jù)源地址都是這樣的:
- <property value=”jdbc:mysql://localhost:3306/dbname/>
復制代碼
假如數(shù)據(jù)庫的編碼格式是utf-8的,這個時候假如服務端發(fā)送給數(shù)據(jù)庫的數(shù)據(jù)的編碼格式不是utf-8的話,存入數(shù)據(jù)庫的數(shù)據(jù)就會變成亂碼。這個時候我們可以通過在配置數(shù)據(jù)源的時候明確指定編碼格式來解決這個問題,配置如下:
- <property value=”jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=utf-8″/>
復制代碼
可以看到只是在原來配置的基礎上增加了一些參數(shù)。
第三種情況是服務端和應用服務器(也就是tomcat)之間的亂碼問題。這個問題不太好發(fā)現(xiàn),因為最開始我遇到這個問題的時候,我從前端html的字符編
碼到數(shù)據(jù)庫字符編碼都查遍了,發(fā)現(xiàn)所有的編碼都是統(tǒng)一的,而且也是支持中文,但是還是會出現(xiàn)亂碼。費了很多周折,查了很多資料才發(fā)現(xiàn)原來是應用服務器的問
題,因為tomcat默認的字符集是ISO-8859-1,所以當使用中文時就會出現(xiàn)亂碼。還好這個問題解決起來也是比較簡單的。首先在tomcat的安
裝目錄下找到conf文件夾,打開該文件夾中的server.xml文件,不同的tomcat版本這個文件可能會有所差別,我用的
tomcat6.0.18,將其中相應的配置修改如下:
-
- <Connector port=”8080″ protocol=”HTTP/1.1″
- connectionTimeout=”20000″
- redirectPort=”8443″
- URIEncoding=”UTF-8″ />
復制代碼
注意,最后一個URIEncoding=”UTF-8″在原來的配置中是沒有的,只要加上這個配置參數(shù),tomcat就能正確識別UTF-8編碼的字符了。
以上就是我在tomcat上做web應用時所遇到的中文亂碼的各種情況,注意文中提到的支持中文編碼的字符集時只是以UTF-8為例,其它比較常用的支持
中文編碼的字符集還有GBK,gb2312等。你可以根據(jù)自己的需要選擇合適的字符集。但一定要記住,不管你選擇使用什么字符集,一旦選定之后,整個應用
都應盡量使用統(tǒng)一的字符編碼格式,盡管某些字符集之間是相互兼容的,但也可能產(chǎn)生不必要的麻煩或者未知的問題。在實際應用中我相信大家也都會遇到各種千奇
百怪的亂碼問題,歡迎大家繼續(xù)補充解決之道,多多益善。 |