天天看點

tomcat中文亂碼問題

在javaweb開發中,使用tomcat,與字元編碼有關的有

浏覽器目前使用的編碼(用于請求資料的編碼),如果是jsp頁面且沒有手動修改浏覽器浏覽器編碼,則就是page指令的pageencoding屬性所指定的編碼

tomcat中文亂碼問題

tomcat的server.xml中的connector元素的uriencoding和usebodyencodingforuri屬性值

uriencoding

this specifies the character encoding used to decode the uri

bytes, after %xx decoding the url. if not specified, iso-8859-1 will

be used.

該屬性用于指定用于解碼uri的字元集,如果未指定則使用iso8859-1

usebodyencodingforuri

this specifies if the encoding specified in contenttype should be

used for uri query parameters, instead of using the uriencoding.

this setting is present for compatibility with tomcat 4.1.x, where

the encoding specified in the contenttype, or explicitly set using

request.setcharacterencoding method was also used for the parameters

from the url. the default value is

false. 

布爾值。若為true,則用contenttype中指定的編碼,或request.setcharacterencoding方法指定的編碼來代替uriencoding屬性所指定的編碼。這個屬性存在的目的是為了相容tomcat4.1.x版本。本文不做測試

request對象的setcharacterencoding方法

在servlet規範中有這樣一段描述,如下:

currently,many

browsers do not send a char encoding qualifier with the content-

typeheader,

leaving open the determination of the character encoding for reading

httprequests.

the default encoding of a request the container uses to create the

request

reader and parse post data must be “iso-8859-1” if none has been

specified

bythe

client request. however, in order to indicate to the developer, in

thiscase, the

failureof

the client to send a character encoding, the container returns null

from

thegetcharacterencoding

method.

if

the client hasn’t set character encoding and therequest data is encoded

with a

differentencoding

than the default as described above, breakage can occur. to

remedythis

situation, a new method setcharacterencoding(string enc) has

beenadded

to the servletrequest interface. developers can override the

characterencoding

supplied by the container by calling this method. it must be

calledprior

to parsing any post data or reading any input from the request.

calling

thismethod

once data has been read will not affect the encoding.

大體意思就是:

現在的大多數浏覽器并不把使用的字元編碼類型包含在header中發送給伺服器。如果用戶端請求中沒有指定字元集,則servlet容器用來建立request

reader和解析post

data所使用的預設字元集必須是iso8859-1。servlet容器通過從getcharacterencoding方法中傳回null,來讓開發者知道用戶端并沒有發送字元集。

當用戶端并沒有使用iso8859-1,而servlet容器仍然使用iso8859-1來解析資料時,就會出現籌碼問題。開發者可以調用setcharacterencoding方法來告訴容器應該使用哪種字元集來解析資料,而且必須在從request中解析任何資料或讀取任何輸入之前調用,否則對已經讀取的資料的字元集無影響。

response對象的setcharacterencoding方法

作用:設定發送到用戶端的response的字元編碼。預設iso8859-1

response.setcontenttype("text/html;charset=utf-8");

上面一行代碼等效于下面兩行代碼

response.setcontenttype("text/html");

response.setcharacterencoding("utf-8");

該方法必須在調動getwriter方法調動,否則起不到任何效果。

system.out.println(response.getcharacterencoding());//輸出utf-8

response.setcharacterencoding("gbk");

system.out.println(response.getcharacterencoding());//輸出gbk

printwriter

pw =response.getwriter();

system.out.println(response.getcharacterencoding());

//輸出utf-8

pw.close();

實驗

,驗證編碼請求資料所使用的字元集由誰來決定,測試文字“中文測試”

pageencoding

request.setcharacterencoding

form中的method屬性

環境如下圖所示:

條件

結果

pageencoding="utf-8"

method="get"

“中文測試”四個字經過url編碼後為:%e4%b8%ad%e6%96%87%e6%b5%8b%e8%af%95

tomcat中文亂碼問題

string utf8 = "utf-8";

string encoded = "%e4%b8%ad%e6%96%87%e6%b5%8b%e8%af%95";

system.out.println(urldecoder.decode(encoded, utf8));

//輸出結果為:中文測試

pageencoding="gbk"

“中文測試”四個字經過url編碼後為:%d6%d0%ce%c4%b2%e2%ca%d4

tomcat中文亂碼問題

string gbk = "gbk";

string encoded = "%d6%d0%ce%c4%b2%e2%ca%d4";

system.out.println(urldecoder.decode(encoded, gbk));

uriencoding="utf-8"

tomcat中文亂碼問題

method="post"

response.jsp檔案主要代碼如下:

<body>

    <form action="request.jsp"

method="post">

        使用者名:<input

name="name" type="text">

        <input

type="submit" value="submit">

    </form>

    <%

        string name =

request.getparameter("name");

        if(name !=

null){

                name

= urlencoder.encode(name, "iso8859-1");

= urldecoder.decode(name, "utf-8");

        }

    %>

    <br/>

    <%= name %>

</body>

輸出結果:

tomcat中文亂碼問題

request.setcharact-erencoding("utf-8")

  <body>

        request.setcharacterencoding("utf-8");

= urlencoder.encode(name, "utf-8");

  </body>

tomcat中文亂碼問題

實驗結論

請求資料所使用的編碼由浏覽器目前使用的編碼決定。

進一步的說明

tomcat的server.xml檔案中的connector元素的uriencoding屬性隻決定tomcat将用哪種編碼來解析url帶到伺服器的資料,也就是通過get請求發送到伺服器的資料。

request.setcharacterencoding方法隻決定tomcat将用哪種編碼來解析post請求中的資料。在jsp檔案中,設定pageencoding屬性值相當于調動了request.setcharacterencoding方法,可以通過request.getcharacterencoding方法進行驗證。

response.setcharacterencoding方法則決定tomcat向用戶端響應資料的編碼,同時也會告訴用戶端使用哪種編碼來顯示資料。通過該方法設定的編碼将能夠通過相應的getcharacterencoding方法取得。在jsp檔案中,response.setcharacterencoding擷取到的是pageencoding屬性的值,也就是說,在jsp檔案中,設定pageencoding屬性的值就相當于在servlet中調用response.setcharacterencoding方法

亂碼類型改解決方案

jsp頁面響應亂碼

通過設定pageencoding屬性為一個支援中文的編碼即可解決。

servlet響應亂碼

通過調用response.setcharacterencoding方法設定一個支援中文的編碼即可解決。

伺服器端擷取get請求資料亂碼

通過設定tomcat的server.xml檔案中connector元素的uriencoding屬性為一個支援中文的編碼即可解決。

伺服器端jsp擷取post請求資料亂碼

伺服器端servlet擷取post請求資料亂碼

通過調用request.setcharacterencoding方法設定一個支援中文的編碼即可解決。

用戶端與tomcat互動過程中的encode與decode圖示

tomcat中文亂碼問題

在不改變tomcat預設字元集iso8859-1的情況下,解決擷取資料時出現亂碼的另一種方案就是,先使用iso8859-1

encode,再使用正确的字元集decode

string

name =request.getparameter("name");

name

=urldecoder.decode(name, "utf-8");