日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux平台Java环境中文编码研究

發布時間:2023/12/20 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux平台Java环境中文编码研究 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

09年在原來公司做的一篇文章,現在共享出來。


此次研究主要針對Linux操作系統中Java環境下可能產生的中文亂碼問題展開一些試驗,目的在于尋求一套無亂碼的解決方案。

此文檔目的在于詳細介紹《2 過程記錄文檔》中得出的相關結論,以及描述建立一個統一編碼環境的具體過程。

?

一、???準備知識

1.???字節、字符、編碼

從計算機對多國語言的支持角度看,大致可以分為三個階段:

 

系統內碼

說明

系統

階段一

ASCII

計算機剛開始只支持英語,其它語言不能夠在計算機上存儲和顯示。

英文 DOS

階段二

ANSI編碼
(本地化)

為使計算機支持更多語言,通常使用 0x80~0xFF 范圍的 2 個字節來表示 1 個字符。比如:漢字 '中' 在中文操作系統中,使用 [0xD6,0xD0] 這兩個字節存儲。

不同的國家和地區制定了不同的標準,由此產生了 GB2312, BIG5, JIS 等各自的編碼標準。這些使用 2 個字節來代表一個字符的各種漢字延伸編碼方式,稱為 ANSI 編碼。在簡體中文系統下,ANSI 編碼代表 GB2312 編碼,在日文操作系統下,ANSI 編碼代表 JIS 編碼。

不同 ANSI 編碼之間互不兼容,當信息在國際間交流時,無法將屬于兩種語言的文字,存儲在同一段 ANSI 編碼的文本中。

中文 DOS,中文 Windows 95/98,日文 Windows 95/98

階段三

UNICODE
(國際化)

為了使國際間信息交流更加方便,國際組織制定了 UNICODE 字符集,為各種語言中的每一個字符設定了統一并且唯一的數字編號,以滿足跨語言、跨平臺進行文本轉換、處理的要求。

Windows NT/2000/XP,Linux,Java

?

字符串在內存中的存放方法:

在 ASCII 階段,單字節字符串使用一個字節存放一個字符(SBCS)。比如,"Bob123"在內存中為:

42

6F

62

31

32

33

00

B

o

b

1

2

3

\0

?

在使用 ANSI 編碼支持多種語言階段,每個字符使用一個字節或多個字節來表示(MBCS),因此,這種方式存放的字符也被稱作多字節字符。比如,"中文123" 在中文 Windows 95 內存中為7個字節,每個漢字占2個字節,每個英文和數字字符占1個字節:

D6

D0

CE

C4

31

32

33

00

1

2

3

\0

?

在 UNICODE 被采用之后,計算機存放字符串時,改為存放每個字符在 UNICODE 字符集中的序號。目前計算機一般使用 2 個字節(16 位)來存放一個序號(DBCS),因此,這種方式存放的字符也被稱作寬字節字符。比如,字符串 "中文123" 在 Windows 2000 下,內存中實際存放的是 5 個序號:

2D

4E

87

65

31

00

32

00

33

00

00

00

1

2

3

\0

?

一共占 10 個字節。

?

理解編碼的關鍵,是要把字符的概念和字節的概念理解準確。這兩個概念容易混淆,我們在此做一下區分:

 

概念描述

舉例

字符

人們使用的記號,抽象意義上的一個符號。

'1', '中', 'a', '$', '¥', ……

字節

計算機中存儲數據的單元,一個8位的二進制數,是一個很具體的存儲空間。

0x01, 0x45, 0xFA, ……

ANSI
字符串

在內存中,如果“字符”是以 ANSI 編碼形式存在的,一個字符可能使用一個字節或多個字節來表示,那么我們稱這種字符串為 ANSI 字符串或者多字節字符串

"中文123"
(占7字節)

UNICODE
字符串

在內存中,如果“字符”是以在 UNICODE 中的序號存在的,那么我們稱這種字符串為 UNICODE 字符串或者寬字節字符串

"中文123"
(占10字節)

?

?

各個國家和地區所制定的不同 ANSI 編碼標準中,都只規定了各自語言所需的“字符”。比如:漢字標準(GB2312)中沒有規定韓國語字符怎樣存儲。這些 ANSI 編碼標準所規定的內容包含兩層含義:

  • 使用哪些字符。也就是說哪些漢字,字母和符號會被收入標準中。所包含“字符”的集合就叫做“字符集”。
  • 規定每個“字符”分別用一個字節還是多個字節存儲,用哪些字節來存儲,這個規定就叫做“編碼”。
  • 各個國家和地區在制定編碼標準的時候,“字符的集合”和“編碼”一般都是同時制定的。因此,平常我們所說的“字符集”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”這層含義外,同時也包含了“編碼”的含義。

    UNICODE 字符集”包含了各種語言中使用到的所有“字符”。用來給 UNICODE 字符集編碼的標準有很多種,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。

    ?

    2.???常用字符集

    簡單介紹一下常用的編碼規則,為后邊的章節做一個準備。在這里,我們根據編碼規則的特點,把所有的編碼分成三類:

    分類

    編碼標準

    說明

    單字節字符編碼

    ISO-8859-1

    最簡單的編碼規則,每一個字節直接作為一個 UNICODE 字符。比如,[0xD6, 0xD0] 這兩個字節,通過 iso-8859-1 轉化為字符串時,將直接得到 [0x00D6, 0x00D0] 兩個 UNICODE 字符,即 "?D"。

    反之,將 UNICODE 字符串通過 iso-8859-1 轉化為字節串時,只能正常轉化 0~255 范圍的字符。

    ANSI 編碼

    GB2312,
    BIG5,
    Shift_JIS,
    ISO-8859-2 ……

    把 UNICODE 字符串通過 ANSI 編碼轉化為“字節串”時,根據各自編碼的規定,一個 UNICODE 字符可能轉化成一個字節或多個字節。

    反之,將字節串轉化成字符串時,也可能多個字節轉化成一個字符。比如,[0xD6, 0xD0] 這兩個字節,通過 GB2312 轉化為字符串時,將得到 [0x4E2D] 一個字符,即 '中' 字。

    “ANSI 編碼”的特點:
    1. 這些“ANSI 編碼標準”都只能處理各自語言范圍之內的 UNICODE 字符。
    2. “UNICODE 字符”與“轉換出來的字節”之間的關系是人為規定的。

    UNICODE 編碼

    UTF-8,
    UTF-16, UnicodeBig ……

    與“ANSI 編碼”類似的,把字符串通過 UNICODE 編碼轉化成“字節串”時,一個 UNICODE 字符可能轉化成一個字節或多個字節。

    與“ANSI 編碼”不同的是:
    1. 這些“UNICODE 編碼”能夠處理所有的 UNICODE 字符。
    2. “UNICODE 字符”與“轉換出來的字節”之間是可以通過計算得到的。

    我們實際上沒有必要去深究每一種編碼具體把某一個字符編碼成了哪幾個字節,我們只需要知道“編碼”的概念就是把“字符”轉化成“字節”就可以了。對于“UNICODE 編碼”,由于它們是可以通過計算得到的,因此,在特殊的場合,我們可以去了解某一種“UNICODE 編碼”是怎樣的規則。

    ?

    二、???亂碼產生過程分析

    為了讓使用Java語言編寫的程序能在各種語言的平臺下運行,Java在其內部使用Unicode字符集來表示字符,這樣就存在了Unicode字符集和本地字符集進行轉換的過程。當在Java中讀取字符數據的時候,需要將本地的字符集編碼的數據轉換為Unicode的編碼,而在輸出字符數據的時候,則需要將Unicode編碼轉換為本地字符集編碼。

    例如,在中文系統下,從控制臺讀取一個字符“中”,實際上讀取的是“中”的GBK編碼0xD6D0,在Java語言下要將GBK編碼轉換為Unicode編碼0x4E2D,此時在內存中字符“中”的對應數值就是0x4E2D,當我們向控制臺輸出字符時,Java語言將Unicode編碼再轉換為GBK編碼,輸出到控制臺,中文系統再根據GBK字符集畫出相應的字符。

    從上述過程來看,讀取和寫入的過程是可逆的,那么理應不會出現中文問題。然而,實際應用的情況,卻復雜的多。在web應用中,通常都包括了瀏覽器、web服務器、web應用程序和數據庫等部分,每一個部分都可能使用不同的字符集,從而導致字符數據在各種不同的字符集之間轉換時出現亂碼問題。

    當從Unicode編碼像某個字符集轉換時,如果在該字符集中沒有對應的編碼,則得到0x3f(即問號字符?)。這就是為什么有時候我們輸入的中文會在輸出時卻變成了問號。從其他字符集向Unicode編碼轉換時,如果這個二進制數在該字符集中沒有標識任何字符,則得到的結果是0xfffd。

    從上述所知,,由于存在著不同的字符集,在各種字符集之間進行轉換,就可能出現亂碼,同樣是中文字符集GB2312和GBK,由于編碼范圍不同某些字符轉換時也會出現亂碼。

    由于瀏覽器會根據本地系統默認的字符集提交數據,而web容器默認采用的是ISO-8859-1的編碼方式解析POST數據,另外JDBC驅動也多采用ISO-8859-1的編碼格式,因此,在web應用程序運行中,輸入的中文字符往往需要在不同的字符集之間來回轉換,這也就導致了中文亂碼問題的頻繁出現。

    下圖描述了在web應用的請求響應過程中,發生編碼轉換的過程,其中瀏覽器是IE,web容器時Tomcat。

    從下圖的描述過程中可以看到,如果在web應用程序不指定任何字符集,從瀏覽器傳來的中文字符,輸出回瀏覽器時,可以正常顯示(以簡體中文的方式查看網頁)。然后,事情并沒有這么簡單,在servlet/jsp中,可能存在直接寫入的或者從其他來源讀取的中文字符,如果這些字符對應的Unicode碼是從GB2312編碼轉換來的,那么以ISO-8859-1編碼方式輸出,這些字符將不能正常顯示。所以對于圖中的中文處理,應在②和⑤的位置明確使用GB2312或者GBK字符集。

    三、???編碼轉換過程分析

    我們常見的JAVA程序包括以下類別:

    l? 直接在console上運行的類(包括可視化界面的類)

    l? JSP代碼類(注:JSP是Servlets類的變型)

    l? Servelets類

    l? EJB類

    l? 其它不可以直接運行的支持類

    ?

    這些類文件中,都有可能含有中文字符串,并且我們常用前三類JAVA程序和用戶直接交互,用于輸出和輸入字符,如:我們在JSP和Servlet中得到客戶端送來的字符,這些字符也包括中文字符。無論這些JAVA類的作用如何,這些JAVA程序的生命周期都是這樣的:

    l? 編程人員在一定的操作系統上選擇一個合適的編輯軟件來實現源程序代碼并以.java擴展名保存在操作系統中,例如我們在中文win2k中用記事本編輯一個java源程序;

    l? 編程人員用JDK中的javac.exe來編譯這些源代碼,形成.class類(JSP文件是由容器調用JDK來編譯的);

    l? 直接運行這些類或將這些類布署到WEB容器中去運行,并輸出結果。

    ?

    那么,在這些過程中,JDK和JVM是如何將這些文件如何編碼和解碼并運行的呢?

    這里,我們以中文win2k操作系統為例說明JAVA類是如何來編碼和被解碼的。

    ???

    第一步,我們在中文win2k中用編輯軟件如記事本編寫一個Java源程序文件(包括以上五類JAVA程序),程序文件在保存時默認采用了操作系統默認支持GBK編碼格式(操作系統默認支持的格式為file.encoding格式)形成了一個.java文件,也即,java程序在被編譯前,我們的JAVA源程序文件是采用操作系統默認支持的file.encoding編碼格式保存的,java源程序中含有中文信息字符和英文程序代碼;要查看系統的file.encoding參數,可以用以下代碼:

    public class ShowSystemDefaultEncoding {

    public static voidmain(String[] args) {

    String encoding =System.getProperty("file.encoding");

    System.out.println(encoding);

    }}

    ?

    第二步,我們用JDK的javac.exe文件編譯我們的Java源程序,由于JDK是國際版的,在編譯的時候,如果我們沒有用-encoding參數指定我們的JAVA源程序的編碼格式,則javac.exe首先獲得我們操作系統默認采用的編碼格式,也即在編譯java程序時,若我們不指定源程序文件的編碼格式,JDK首先獲得操作系統的file.encoding參數(它保存的就是操作系統默認的編碼格式,如WIN2k,它的值為GBK),然后JDK就把我們的java源程序從file.encoding編碼格式轉化為JAVA內部默認的UNICODE格式放入內存中。然后,javac把轉換后的unicode格式的文件進行編譯成.class類文件,此時.class文件是UNICODE編碼的,它暫放在內存中,緊接著,JDK將此以UNICODE編碼的編譯后的class文件保存到我們的操作系統中形成我們見到的.class文件。對我們來說,我們最終獲得的.class文件是內容以UNICODE編碼格式保存的類文件,它內部包含我們源程序中的中文字符串,只不過此時它己經由file.encoding格式轉化為UNICODE格式了。

    ??? 這一步中,對于JSP源程序文件是不同的,對于JSP,這個過程是這樣的:即WEB容器調用JSP編譯器,JSP編譯器先查看JSP文件中是否設置有文件編碼格式,如果JSP文件中沒有設置JSP文件的編碼格式,則JSP編譯器調用JDK先把JSP文件用JVM默認的字符編碼格式(也即WEB容器所在的操作系統的默認的file.encoding)轉化為臨時的Servlet類,然后再把它編譯成UNICODE格式的class類,并保存在臨時文件夾中。如:在中文win2k上,WEB容器就把JSP文件從GBK編碼格式轉化為UNICODE格式,然后編譯成臨時保存的Servlet類,以響應用戶的請求。

    ??? 第三步,運行第二步編譯出來的類,分為三種情況:

    ??? A、直接在console上運行的類

    ??? B、 EJB類和不可以直接運行的支持類(如JavaBean類)

    ??? C、 JSP代碼和Servlet類

    ??? D、 JAVA程序和數據庫之間

    ??? 下面我們分這四種情況來看。

    1.???直接在console上運行的類

    這種情況,運行該類首先需要JVM支持,即操作系統中必須安裝有JRE。運行過程是這樣的:首先java啟動JVM,此時JVM讀出操作系統中保存的class文件并把內容讀入內存中,此時內存中為UNICODE格式的class類,然后JVM運行它,如果此時此類需要接收用戶輸入,則類會默認用file.encoding編碼格式對用戶輸入的串進行編碼并轉化為unicode保存入內存(用戶可以設置輸入流的編碼格式)。程序運行后,產生的字符串(UNICODE編碼的)再回交給JVM,最后JRE把此字符串再轉化為file.encoding格式(用戶可以設置輸出流的編碼格式)傳遞給操作系統顯示接口并輸出到界面上。

    ??? 對于這種直接在console上運行的類,它的轉化過程可用下圖更加明確的表示出來:

    ? 以上每一步的轉化都需要正確的編碼格式轉化,才能最終不出現亂碼現象。

    2.???EJB類和不可以直接運行的支持類

    由于EJB類和不可以直接運行的支持類,它們一般不與用戶直接交互輸入和輸出,它們常常與其它的類進行交互輸入和輸出,所以它們在第二步被編譯后,就形成了內容是UNICODE編碼的類保存在操作系統中了,以后只要它與其它的類之間的交互在參數傳遞過程中沒有丟失,則它就會正確的運行。

    這種EJB類和不可以直接運行的支持類, 它的轉化過程可用下圖更加明確的表示出來:

    3.???JSP代碼和Servlet類

    經過第二步后,JSP文件也被轉化為Servlets類文件,只不過它不像標準的Servlets一校存在于classes目錄中,它存在于WEB容器的臨時目錄中,故這一步中我們也把它做為Servlets來看。

    對于Servlets,客戶端請求它時,WEB容器調用它的JVM來運行Servlet,首先,JVM把Servlet的class類從系統中讀出并裝入內存中,內存中是以UNICODE編碼的Servlet類的代碼,然后JVM在內存中運行該Servlet類,如果Servlet在運行的過程中,需要接受從客戶端傳來的字符如:表單輸入的值和URL中傳入的值,此時如果程序中沒有設定接受參數時采用的編碼格式,則WEB容器會默認采用ISO-8859-1編碼格式來接受傳入的值并在JVM中轉化為UNICODE格式的保存在WEB容器的內存中。

    Servlet運行后生成輸出,輸出的字符串是UNICODE格式的,緊接著,容器將Servlet運行產生的UNICODE格式的串(如html語法,用戶輸出的串等)直接發送到客戶端瀏覽器上并輸出給用戶,如果此時指定了發送時輸出的編碼格式,則按指定的編碼格式輸出到瀏覽器上,如果沒有指定,則默認按ISO-8859-1編碼發送到客戶的瀏覽器上。

    這種JSP代碼和Servlet類,它的轉化過程可用下圖更加明確地表示出來:

    4.???JAVA程序和數據庫之間

    對于幾乎所有數據庫的JDBC驅動程序,默認的在JAVA程序和數據庫之間傳遞數據都是以ISO-8859-1為默認編碼格式的,所以,我們的程序在向數據庫內存儲包含中文的數據時,JDBC首先是把程序內部的UNICODE編碼格式的數據轉化為ISO-8859-1的格式,然后傳遞到數據庫中,在數據庫保存數據時,它默認即以ISO-8859-1保存,所以,這是為什么我們常常在數據庫中讀出的中文數據是亂碼。
    ?????? 對于JAVA程序和數據庫之間的數據傳遞,我們可以用下圖清晰地表示出來:

    四、???分析亂碼的原則

    首先,經過上面的詳細分析,我們可以清晰地看到,任何JAVA程序的生命期中,其編碼轉換的關鍵過程是在于:最初編譯成class文件的轉碼和最終向用戶輸出的轉碼過程。

    ??? 其次,我們必須了解JAVA在編譯時支持的、常用的編碼格式有以下幾種:

    l? ISO-8859-1,8-bit, 同8859_1,ISO-8859-1,ISO_8859_1等編碼

    l? Cp1252,美國英語編碼,同ANSI標準編碼

    l? UTF-8,同unicode編碼

    l? GB2312,同gb2312-80,gb2312-1980等編碼

    l? GBK , 同MS936,它是gb2312的擴充

    ??? 及其它的編碼,如韓文、日文、繁體中文等。同時,我們要注意這些編碼間的兼容關體系如下:

    ??? Unicode和UTF-8編碼是一一對應的關系。GB2312可以認為是GBK的子集,即GBK編碼是在gb2312上擴展來的。同時,GBK編碼包含了20902個漢字,編碼范圍為:0x8140-0xfefe,所有的字符可以一一對應到UNICODE2.0中來。

    ??? 再次,對于放在操作系統中的.java源程序文件,在編譯時,我們可以指定它內容的編碼格式,具體來說用-encoding來指定。注意:如果源程序中含有中文字符,而你用-encoding指定為其它的編碼字符,顯然是要出錯的。用-encoding指定源文件的編碼方式為GBK或gb2312,無論我們在什么系統上編譯含有中文字符的JAVA源程序都不會有問題,它都會正確地將中文轉化為UNICODE存儲在class文件中。

    然后,我們必須清楚,幾乎所有的WEB容器在其內部默認的字符編碼格式都是以ISO-8859-1為默認值的,同時,大多數的瀏覽器在傳遞參數時都是默認以UTF-8的方式來傳遞參數的(IE有時候是根據本地系統的語言環境來定編碼)。所以,雖然我們的Java源文件在出入口的地方指定了正確的編碼方式,但其在容器內部運行時還是以ISO-8859-1來處理的。

    五、???統一編碼的解決方案

    綜上所述,建立一個統一編碼的環境是避免亂碼問題產生的最好方法。而為了支持更多的語言,我們最好選擇UTF-8來作為統一的編碼字符集。以下是Linux下建立統一編碼環境的步驟。

    1.???Linux的設置

    按照教程指導的安裝過程會缺少中文字體安裝包,所以首先安裝中文支持:

    # rpm -ivh --forcefonts-ISO8859-2-100dpi-1.0-17.1.noarch.rpm

    # rpm -ivh --force fonts-ISO8859-2-1.0-17.1.noarch.rpm

    # rpm -ivh --force fonts-ISO8859-2-75dpi-1.0-17.1.noarch.rpm

    # rpm -ivh --forcefonts-chinese-3.02-12.el5.noarch.rpm

    # fc-cache -f -v

    ?

    然后設置語言環境:

    編輯/etc/sysconfig/i18n,修改內容如下:

    LANG="zh_CN.UTF-8"

    SUPPORTED="zh_CN.UTF-8:zh_CN:zh:en_US.UTF-8:en_US:en"

    SYSFONT="latarcyrheb-sun16"

    ?

    編輯/etc/profile,加入:

    export LC_ALL=zh_CN.UTF-8

    ?

    2.???JVM的設置

    JVM的缺省編碼方式由系統的“本地語言環境Locale”設置確定。JVM的file.encoding屬性,這個屬性確定了JVM的缺省的編碼/解碼方式:從而影響應用中所有字節流==>字符流的解碼方式 ,字符流==>字節流的編碼方式。JVM會根據操作系統的Locale設置自動調整語言環境。基本不用設置。

    3.???Tomcat的設置

    為了使Tomcat支持中文文件名并且讓Tomcat能夠自己處理Get方式傳遞過來的參數,那么我們已經在Tomcat安裝目錄下的conf/server.xml里頭修改如下:

    ??? <Connectorport="8080" protocol="HTTP/1.1"

    ??????????????connectionTimeout="20000"

    ??????????????redirectPort="8443" URIEncoding="UTF-8"/>

    注意一種特殊情況,如果在程序中調用response.sendRedirect()方法重定向到中文文件名的頁面,需要以如下方式調用:

    ???????????????????? response.sendRedirect(java.net.URLEncoder.encode(“中文.html”,”UTF-8”))

    也就是在使用重定向語句的時候,需要用java.net.URLEncoder的靜態方法 encoder() 按照指定的編碼手動轉碼。

    4.???JSP頁面編碼設置

    關于JSP頁面中的pageEncoding和contentType兩種屬性的區別:

    pageEncoding是jsp文件本身的編碼

    contentType的charset是指服務器發送給客戶端時的內容編碼

    ?

    JSP要經過兩次的“編碼”,第一階段會用pageEncoding,第二階段會用utf-8至utf-8,第三階段就是由Tomcat出來的網頁, 用的是contentType。

    ?

    第一階段是jsp編譯成.java,它會根據pageEncoding的設定讀取jsp,結果是由指定的編碼方案翻譯成統一的UTF-8 JAVA源碼(即.java),如果pageEncoding設定錯了,或沒有設定,出來的就是中文亂碼。

    ?

    第二階段是由JAVAC的JAVA源碼至java byteCode的編譯,不論JSP編寫時候用的是什么編碼方案,經過這個階段的結果全部是UTF-8的encoding的java源碼。

    ?

    JAVAC用UTF-8的encoding讀取java源碼,編譯成UTF-8 encoding的二進制碼(即.class),這是JVM對常數字串在二進制碼(java encoding)內表達的規范。

    ?

    第三階段是Tomcat(或其的application container)載入和執行階段二的來的JAVA二進制碼,輸出的結果,也就是在客戶端見到的,這時隱藏在階段一和階段二的參數contentType就發揮了功效。

    ?

    對于每個JSP頁面,為了讓它使用Utf-8的編碼去返回給瀏覽器,那么加入下面一行在頁面開始是必不可少的:

    <%@page contentType="text/html;charset=utf-8"%>

    ?

    5.???使用過濾器

    過濾器是用來統一設置一個web項目中request的處理編碼的方便快捷的方法,它相當于在每個JSP頁面上都設置了request.setCharacterEncoding("utf-8")。

    ?

    其中一種過濾器的代碼如下:

    ?

    package filters;

    ?

    import java.io.IOException;

    import javax.servlet.Filter;

    import javax.servlet.FilterChain;

    import javax.servlet.FilterConfig;

    import javax.servlet.ServletException;

    import javax.servlet.ServletRequest;

    import javax.servlet.ServletResponse;

    import javax.servlet.UnavailableException;

    ?

    public class SetCharacterEncodingFilter implements Filter {

    protected String encoding = null;

    protected FilterConfig filterConfig = null;

    protected boolean ignore = true;

    ?

    public void destroy() {

    this.encoding = null;

    this.filterConfig = null;

    }

    ?

    public void doFilter(ServletRequest request, ServletResponseresponse,FilterChain chain)

    throws IOException, ServletException {

    ?

    // 設置正確的編碼方式

    if (ignore || (request.getCharacterEncoding() == null)) {

    String encoding = selectEncoding(request);

    if (encoding != null)

    request.setCharacterEncoding(encoding);

    }

    ?

    // 傳遞到下一層過濾器

    chain.doFilter(request, response);

    ?

    }

    ?

    public void init(FilterConfig filterConfig) throws ServletException{

    ?

    this.filterConfig = filterConfig;

    this.encoding = filterConfig.getInitParameter("encoding");

    String value = filterConfig.getInitParameter("ignore");

    if (value == null)

    this.ignore = true;

    else if (value.equalsIgnoreCase("true"))

    this.ignore = true;

    else if (value.equalsIgnoreCase("yes"))

    this.ignore = true;

    else

    this.ignore = false;

    ?

    }

    ?

    protected String selectEncoding(ServletRequest request) {

    return (this.encoding);

    }

    ?

    }

    ?

    將它編譯完成后放置到WEB-INF\classes\filters目錄下,然后在修改WEB-INF\web.xml,加入:

    <filter>

    ?????? <filter-name>SetCharacter Encoding</filter-name>

    ?????? <filter-class>filters.SetCharacterEncodingFilter</filter-class>

    ?????? <init-param>

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

    ????????????? <param-value>utf-8</param-value>

    ?????? </init-param>

    ?</filter>

    ?

    ?<filter-mapping>

    ?????? <filter-name>SetCharacter Encoding</filter-name>

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

    ?</filter-mapping>

    ?

    6.???數據庫和數據表編碼設置

    安裝數據庫時如果需要將其配置成Utf-8的默認編碼,那么可以在安裝步驟configure的時候加入參數--with-charset=utf8。

    ?

    安裝過數據庫之后如果想修改數據庫的默認編碼,那么應該這么做:

    修改mysql默認編碼設置:

    # vi /usr/local/mysql/mysql3306/etc/my.cnf

    在[client]下添加

    default-character-set=utf8

    在[mysqld]下添加

    default-character-set=utf8

    ?

    新建數據表時,如果在語句中設置DEFAULT CHARSET,那么將會使用數據庫的默認編碼,數據表的字段也可以單獨設置編碼,如果沒有設置則是使用數據表的默認編碼。

    六、???參考資料

    Linux下Java程序中文亂碼問題研究

    Java和J2EE的中文編碼問題終極解決之道

    Java的中文處理學習筆記:Hello Unicode

    Linux 下 Java 中文環境設置方法

    Java 關于中文亂碼問題的解決方案與經驗

    JSP中文亂碼問題的解決

    Java/JSP中文亂碼問題解決心得

    fc5啟動提示cannot open font file none

    LINUX支持中文

    centos 英文環境下安裝中文輸入法

    在PC上搭建CentOSLinux系統

    tomcat中文問題(轉)

    java byte與char互轉原理

    UTF-8 and Unicode FAQ

    用例子詳細介紹各種字符集編碼轉換問題

    WEB開發中的JAVA字符編碼經驗總結

    JSP和Servlet中的幾個編碼的作用及原理

    Java編碼格式問題大總結

    深入剖析Java編程中的中文問題及建議最優解決方法--上篇

    深入剖析Java編程中的中文問題及建議最優解決方法---下篇

    小談MySQL字符集

    MySQL字符集詳解(一)

    MYSQL教程:MYSQL字符集支持

    解決Tomcat 5.0.19 中文參數傳遞問題

    字符,字節和編碼 - Characters, BytesAnd Encoding

    ?

    總結

    以上是生活随笔為你收集整理的Linux平台Java环境中文编码研究的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。