張學(xué)誠(chéng)
摘要:在Java web開(kāi)發(fā)中,處理中文字符時(shí)經(jīng)常會(huì)出現(xiàn)亂碼問(wèn)題。該文從 Java Web工程字符編碼理論出發(fā),介紹了java Web程序開(kāi)發(fā)中常用的字符編碼集,分析出現(xiàn)中文亂碼的原因,并給出解決方法。
關(guān)鍵詞:亂碼;編碼;解碼
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼: A 文章編號(hào):1009-3044(2018)27-0062-02
Solution of Chinese Messy Code in JavaWeb Development
ZHANG Xue-cheng
(Qufu Normal University Network Infomation Center, Rizhao 276826, China)
Abstract: In the development of Java web, the problem of messy code is often encountered when dealing with Chinese characters. Starting from Java Web engineering character coding theory in this paper, introduces the character encoding set commonly used in Java Web program development,analyzes the cause of chinese garbled code,and then gives the solution.
Key words: Chinese garbled; encoded; decoded
1 背景
Java語(yǔ)言是純面向?qū)ο蟮恼Z(yǔ)言,具有與平臺(tái)無(wú)關(guān)性、較好的安全性、健壯性和提供很多內(nèi)置的類庫(kù)等優(yōu)點(diǎn)。Java支持網(wǎng)絡(luò)傳輸與數(shù)據(jù)庫(kù)存取、已廣泛應(yīng)用于移動(dòng)互聯(lián)網(wǎng)、網(wǎng)絡(luò)開(kāi)發(fā)平臺(tái)等領(lǐng)域,越來(lái)越成為卓越的開(kāi)發(fā)平臺(tái),被廣大編程工作者和企業(yè)級(jí)開(kāi)發(fā)使用,成為移動(dòng)開(kāi)發(fā)、數(shù)據(jù)挖掘和大數(shù)據(jù)等系統(tǒng)開(kāi)發(fā)的首先開(kāi)發(fā)語(yǔ)言。
在Java web開(kāi)發(fā)中,處理中文字符時(shí)經(jīng)常會(huì)出現(xiàn)亂碼,中文亂碼問(wèn)題經(jīng)常困擾著開(kāi)發(fā)人員,給軟件開(kāi)發(fā)工作帶來(lái)很多麻煩。產(chǎn)生亂碼的主要原因是瀏覽器與業(yè)務(wù)組件、業(yè)務(wù)組件與數(shù)據(jù)庫(kù)之間所采用的編碼不同,導(dǎo)致程序在調(diào)試運(yùn)行時(shí)會(huì)在瀏覽器或數(shù)據(jù)庫(kù)中顯示亂碼。該文分析了java web開(kāi)發(fā)過(guò)程中幾種產(chǎn)生亂碼的情況和原因,并給出了不同情況下解決亂碼問(wèn)題方法。
2 java web編程中常用編碼
在Java Web應(yīng)用開(kāi)發(fā)中,字符編碼轉(zhuǎn)換是必要的過(guò)程。計(jì)算機(jī)只能識(shí)別二進(jìn)制數(shù),我們平時(shí)用的字母、阿拉伯?dāng)?shù)字和漢字等,都是通過(guò)字符編碼以二進(jìn)制的形式存放在計(jì)算機(jī)中的。計(jì)算機(jī)處理字符有編碼和解碼兩個(gè)過(guò)程,字符存入計(jì)算機(jī)中轉(zhuǎn)換成二進(jìn)制數(shù)是編碼過(guò)程,反之,把計(jì)算機(jī)中的二進(jìn)制編碼顯示為字符是解碼過(guò)程。
在java web編程中經(jīng)常涉及的字符編碼方式有ISO8859-1,UTF-8,Unicode,GB2312,GBK等,不同編碼方式有不同的編碼規(guī)則。
ISO-8859-1編碼是單字節(jié)編碼,向下兼容ASCII,共能表示256個(gè)字符,該編碼不支持中文。
GBK2312是簡(jiǎn)體中文的字符集編碼,是雙字節(jié)編碼,共包含6763個(gè)漢字。而GBK是GBK2312的擴(kuò)展,兼容GB2312編碼,GB2312只能表示簡(jiǎn)體字, GBK同時(shí)兼容繁體字和簡(jiǎn)體字。
Unicode碼擴(kuò)展自ASCII字元集,使用全16位元字元集,可以用來(lái)表示所有語(yǔ)言的字符,屬于最統(tǒng)一的編碼。
UTF-8(8-bit Unicode Transformation Format)是一種針對(duì)Unicode的可變長(zhǎng)度字符編碼,又稱萬(wàn)國(guó)碼。UTF-8用1到6個(gè)字節(jié)編碼Unicode字符,用在網(wǎng)頁(yè)上可以統(tǒng)一頁(yè)面顯示中文簡(jiǎn)體繁體及其他語(yǔ)言。
3 java web編程編碼轉(zhuǎn)換機(jī)制
用戶從客戶端發(fā)起一個(gè)HTTP請(qǐng)求時(shí),需要先對(duì)URL、Parameter、Cookie等數(shù)據(jù)進(jìn)行編碼,再發(fā)送到服務(wù)器端。服務(wù)器端接收到 HTTP 請(qǐng)求后要分析 HTTP 協(xié)議,對(duì)其中的 URI、POST(或GET)數(shù)據(jù)、 Cookie 和表單參數(shù)等進(jìn)行解碼。服務(wù)器端有時(shí)還需要讀取數(shù)據(jù)庫(kù)中的數(shù)據(jù),以及本地或其他網(wǎng)絡(luò)服務(wù)器中的文件,這些數(shù)據(jù)都可能存在編碼問(wèn)題。當(dāng)應(yīng)用程序處理完用戶請(qǐng)求的數(shù)據(jù)后,需要將這些數(shù)據(jù)再次編碼通過(guò)網(wǎng)絡(luò)發(fā)送到客戶端,再經(jīng)過(guò)瀏覽器解碼,在頁(yè)面顯示。上述過(guò)程圖1所示。
java web開(kāi)發(fā)中經(jīng)常用到的軟件有java編譯器、瀏覽器、數(shù)據(jù)庫(kù)系統(tǒng)、web服務(wù)軟件和開(kāi)發(fā)工具,在使用這些軟件時(shí),了解各種軟件的默認(rèn)編碼和如何更改默認(rèn)編碼,才能有效地避免亂碼問(wèn)題。
4 java web編程中亂碼問(wèn)題及解決辦法
4.1 Eclipse開(kāi)發(fā)環(huán)境編碼設(shè)置
用Eclipse做java web開(kāi)發(fā)時(shí),為了避免出現(xiàn)中文亂碼問(wèn)題,可以在編寫(xiě)jsp頁(yè)面時(shí)設(shè)置默認(rèn)編碼。為了實(shí)現(xiàn)中文顯示并與國(guó)際接軌,一般把Eclipse的編碼方式設(shè)置為UTF-8,通過(guò)以下3個(gè)步驟完成設(shè)置。
首先,設(shè)置jsp面頁(yè)編碼,在window-preferences-General-Content Type-Text-Jsp,設(shè)置Default EnCoding為UTF-8。
然后,設(shè)置Eclipse工作環(huán)境編碼,在window-preferences-General-workspace面板中,設(shè)置Text file encoding為UTF-8。
最后,設(shè)置Jsp文件編碼,在window-preferences-Web-JSP Files面板中,設(shè)置Encoding的編碼為UTF-8。
4.2 jsp頁(yè)面顯示中文編碼設(shè)置
訪問(wèn)JSP頁(yè)面時(shí),中文亂碼是網(wǎng)頁(yè)應(yīng)用開(kāi)發(fā)中較普遍、復(fù)雜性較低的一種亂碼問(wèn)題,為了避免出現(xiàn)亂碼現(xiàn)象,通常在JSP文件頭部添加字符集并指定頁(yè)面編碼格式為UTF-8,代碼如下:
<%@ page language="java" contentType="text/html"; charset="UTF-8" PageEncoding="UFT-8" %>
<!DOCTYPE html>
另外,需要在tomcat web服務(wù)器的配置文件Server.xml的Connecter項(xiàng)中,加入U(xiǎn)RIEncoding="UTF-8",重新啟動(dòng)tomcat服務(wù)。加入的代碼如下。
4.3 jsp頁(yè)面提交信息編碼設(shè)置
瀏覽器向服務(wù)器提交信息有兩種方式,一種是get方式,另一種是post方式。兩種方式需要不同的方法解決亂碼問(wèn)題。
用get方式提交信息時(shí),URL與參數(shù)的連接形式使用“?參數(shù)名1=值1&參數(shù)名2=值2…”的方式,提交的數(shù)據(jù)集為ASCII字符。當(dāng)表單提交時(shí),瀏覽器對(duì)URL中的非ASCII字符進(jìn)行URL編碼,并以ISO8859-1編碼的方式發(fā)送給服務(wù)器,服務(wù)器接收到數(shù)據(jù)后再對(duì)其進(jìn)行解碼。因此,解決get方式提交數(shù)據(jù)時(shí)出現(xiàn)的亂碼問(wèn)題,可以在業(yè)務(wù)層中通過(guò)String類的getBytes方法對(duì)傳來(lái)的參數(shù)進(jìn)行解碼,解碼語(yǔ)句如下:
New String(request.getParameter("name").getBytes("ISO-8859-1"),"客戶編碼方式")
用Post方式提交數(shù)據(jù)時(shí),瀏覽器也會(huì)對(duì)提交的數(shù)據(jù)進(jìn)行編碼,編碼的方式由網(wǎng)頁(yè)中語(yǔ)句設(shè)定,tomcat默認(rèn)為ISO8859-1,為了避免出現(xiàn)亂碼,可以在業(yè)務(wù)層中使用request.setCharacterEncoding("UTF-8或GBK或gb2312")語(yǔ)句來(lái)解碼。
4.4 頁(yè)面鏈接中的亂碼問(wèn)題
在頁(yè)面上查詢或提交某些信息的時(shí)候,鏈接的URL地址中可能包含中文,格式為“網(wǎng)址/中文目錄1/中文文件名.jsp”等。在開(kāi)發(fā)和使用中,業(yè)務(wù)層讀到的中文目錄名或文件名會(huì)有亂碼情況。分析原因是,利用URL傳遞參數(shù)時(shí),程序中的編碼與瀏覽器的編碼環(huán)境有關(guān),也就是說(shuō)URL中包含中文目錄名或中文文件名時(shí),對(duì)參數(shù)值的編碼是根據(jù)瀏覽器的默認(rèn)編碼進(jìn)行的,編碼后傳遞至后臺(tái)再進(jìn)行解碼。由于沒(méi)有進(jìn)行任何處理,此時(shí)請(qǐng)求URL,當(dāng)URL中存在中文時(shí),就會(huì)出現(xiàn)中文亂碼問(wèn)題。
經(jīng)過(guò)研究測(cè)試,成功的解決辦法是對(duì)鏈接進(jìn)行編碼和解碼。編碼的關(guān)鍵代碼如下。
對(duì)鏈接地址進(jìn)行解碼的關(guān)鍵代碼如下。
java.net.URLDecoder.decode(request.getRequestURI(), "UTF-8");
4.5 mysql數(shù)據(jù)庫(kù)的中文編碼設(shè)置
MySQL數(shù)據(jù)庫(kù)默認(rèn)編碼是ISO8859-1。為了避免存取數(shù)據(jù)時(shí)出現(xiàn)中文亂碼問(wèn)題,可以通過(guò)修改MySQL的默認(rèn)編碼為UTF-8實(shí)現(xiàn)。方法是找到MySQL 安裝目錄中的my.ini文件。在 client、 mysqld、 mysql、mysql.server和mysqld_safe項(xiàng)下面均加上default-character-set=utf8。另外,還需要在數(shù)據(jù)庫(kù)鏈接URL中使用jdbc:mysql://localhost:3306/db1?useEncode=true&characterEncoding;=UTF8 為連接字符串URL,其中characterEncoding =utf8是關(guān)鍵代碼,表示連接對(duì)象采用UTF-8編碼字符集。
5 結(jié)束語(yǔ)
中文亂碼問(wèn)題經(jīng)常困擾開(kāi)發(fā)人員,給軟件開(kāi)發(fā)工作帶來(lái)很多麻煩。在應(yīng)用開(kāi)發(fā)中,處理亂碼問(wèn)題,首先要抓住產(chǎn)生亂碼的原因,按照瀏覽器界面、數(shù)據(jù)接收業(yè)務(wù)、數(shù)據(jù)保存、數(shù)據(jù)讀取和處理數(shù)據(jù)回顯給用戶的順序,查找問(wèn)題出現(xiàn)在哪一步,采取相應(yīng)的解決辦法。
參考文獻(xiàn):
[1] 賈曉芳, 沈澤剛. Java Web應(yīng)用開(kāi)發(fā)中的常見(jiàn)亂碼形式及解決方法[J]. 軟件導(dǎo)刊, 2017, 16(4):214-216.
[2] 任憲臻, 梁宏英. JSP頁(yè)面中文亂碼解決方法[J]. 數(shù)字技術(shù)與應(yīng)用, 2017(1):154-154, 157.
[3] 周兵. Java Web開(kāi)發(fā)中的中文亂碼問(wèn)題分析及解決方案[J]. 電腦知識(shí)與技術(shù), 2014, 10(29):6884-6888.
[通聯(lián)編輯:;謝媛媛]