比如以下兩個(gè)jsp頁(yè)面之間的傳遞:
a.jsp頁(yè)面內容:
<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<form action="b.jsp">
name:<input type=text name=name>
<input type=submit>
</form>
b.jsp頁(yè)面內容:
<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<%
String name=request.getParameter("name");
%>
<body>
<%=name%>
</body>
現象:中文亂碼,比如“??????”
解決方法如下:
方法一:-----------嘗試過(guò),有效但確實(shí)不可取
1. 在b.jsp中把pageEncoding="GB2312"改為pageEncoding="ISO8859-1"
雖然這樣b.jsp頁(yè)面顯示的內容還是亂碼,但是不是那種“??????”的亂碼,
而是一些特殊字符
2. 然后在瀏覽器中查看菜單中修改成GB2312的編碼,這時(shí)亂碼就顯示中文了。
3. 但是這種方法是不可行的。
方法二:---------- 嘗試過(guò),有效。我的部分頁(yè)面就是用該方法
1. 在b.jsp中把String name=request.getParameter("name");修改為
String name=new String(request.getParameter("name").getBytes("ISO-8859-1"),"GB2312");
2. 這時(shí)再在頁(yè)面上顯示,則就是中文了。
3. 但是我個(gè)人不喜歡這種方法,因為編寫(xiě)起來(lái)代碼非常繁瑣
方法三:
1. 有人說(shuō)修改get/post的傳值方式,但是這是有前提的,
如果只是把get方式修改成post方式,頁(yè)面結果還是亂碼!
2. 前提你必須配置了過(guò)濾器,若果你只是配置了過(guò)濾器,
則傳值方式必須是:post方式才不是亂碼,如果是get方式照樣是亂碼!
3. 過(guò)濾器的配置,我想大家都能有,我就不說(shuō)了
方法四:
1. 有人說(shuō)配置tomcat的配置文件server.xml里這句:
<Connector URIEncoding="GB2312"
port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
加上這句:URIEncoding="GB2312"
2. 雖然可以但是有前提的,若果你過(guò)濾器沒(méi)有配置,
則只是配置了server.xml文件,這樣只有在表單是get傳值時(shí)候才可以!
當是post方式時(shí),照樣是亂碼!
*這時(shí)我們就可以看出在tomcat5中的post與get傳值方式是不一樣的*
*有人要問(wèn)有沒(méi)有一種方法讓傳值使用get方式或post方式都好用呢,
下面就是我推薦的方法五*
方法五:
1. 其實(shí)很簡(jiǎn)單,就是同時(shí)實(shí)現方法三又實(shí)現方法四!
2. 就是先配置過(guò)濾器,又配置server.xml文件,都設置成GB2312的編碼
3. 這樣無(wú)論是post還是get方式的表單傳值,中文都不會(huì )是亂碼!
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
亂碼對于使用非英語(yǔ)文字程序員基本上是一直纏繞在身邊的麻煩事,這個(gè)誰(shuí)也避免不了。下面是我解決
亂碼時(shí)候的一點(diǎn)小經(jīng)驗。歡迎指正
一、避免
亂碼的一些注意點(diǎn):
1.盡量使用統一的編碼,如果你是重頭開(kāi)發(fā)一個(gè)系統,特別是
Java開(kāi)發(fā)的,推薦從頁(yè)面到數據庫再到配置文件都使用UTF-8進(jìn)行編碼,安全第一。
2.SetCharacterEncodingFilter的使用,這個(gè)東西不是萬(wàn)能的,但是沒(méi)有它就會(huì )很麻煩,如果是基于Servlet開(kāi)發(fā)的東西,能用的就給它用上,省心。不過(guò)有一個(gè)注意的地方,這個(gè)Filter只是對POST請求有效,
GET一律忽略,不信你可以debug一下,看看它怎么做的,至于為什么不過(guò)濾
get請求,好象是它對
GET請求是無(wú)能為力的。
3.就如上面所說(shuō),
GET請求有問(wèn)題,盡量使用POST請求,這個(gè)也是Web開(kāi)發(fā)的一個(gè)基本要領(lǐng):
Web Health Warning:Put All Destructive Actions Behind a POST method(from Agile Web Development with Rails)
有點(diǎn)扯遠了,不過(guò)少用
GET,是會(huì )有回報滴。
4.
JavaScript和Ajax
亂碼的避免,注意
JavaScript默認是ISO8859的編碼,避免JS/AJAX
亂碼和
GET一樣,不要在URL里面使用中文,實(shí)在避免不了,就只能在生成鏈接的時(shí)候轉碼,絕對不能想當然的認為SetCharacterEncodingFilter會(huì )幫你做什么事情。
5.盡早統一開(kāi)發(fā)環(huán)境,早點(diǎn)模擬真實(shí)環(huán)境測試,這個(gè)好像也有跑題的嫌疑,但凡軟件開(kāi)發(fā)都是這么干的,但仍然值得注意。我這出現過(guò)一次狀況,程序是在Win下編譯的,拿去Linux上測試沒(méi)問(wèn)題,等實(shí)際部署的時(shí)候代碼是在Linux下編譯,結果
亂碼,秋后算帳總覺(jué)得有點(diǎn)晚。
二、
亂碼發(fā)生的情況和應對措施
1.開(kāi)發(fā)環(huán)境
亂碼
由于
Java默認使用UTF-8編碼,而且網(wǎng)上很多人都建議Struts開(kāi)發(fā)的時(shí)候應盡量選用UTF-8做為默認編碼,而非GBK。IDE使 用Eclipse,在第一次使用Eclipse的時(shí)候應將default text editor改為UTF-8編碼,免得日后后悔再改就慘了,我本次開(kāi)發(fā)的時(shí)候就忽視了這一點(diǎn),剛開(kāi)始沒(méi)注意,結果到快交工時(shí)
亂碼問(wèn)題無(wú)法解決,導致將所有 的文件全部修改一遍,嗚……
自打使用Ubuntu,我就開(kāi)心的笑阿,再也不用為搞這些
亂碼問(wèn)題而煩惱^^(Ubuntu公益廣告)
2.POST請求的過(guò)濾
這個(gè)是最基本的了,每個(gè)Servlet系統基本都會(huì )用到這個(gè)東西。不過(guò)只對POST請求有效,這個(gè)挺關(guān)鍵的。
使用SetCharacterEncodingFilter,這個(gè)很基礎的一套過(guò)濾器,將所有來(lái)自頁(yè)面的POST請求全部過(guò)濾為UTF-8編碼。
3. JSP ,HTML頁(yè)面
亂碼
將JSP頁(yè)面全部改為charset=UTF-8,這樣可以保證與后臺交互的時(shí)候都是UTF-8編碼,一般應用做了以上工作就基本可以應付了。
4.資源文件中漢字轉化UTF-8字符問(wèn)題
國際化問(wèn)題,在使用資源文件的時(shí)候,由于中文在properties文件中無(wú)法被程序所識別,需要將其進(jìn)行轉碼,我在資源文件下面制作了一個(gè)很簡(jiǎn)單的 bat文件,每次修改資源文件的時(shí)候都是在一個(gè)臨時(shí)文件中修改,然后執行這個(gè)bat文件,將其轉化并保存為所需要的資源文件,這個(gè)動(dòng)作挺煩的,也有項目組 成員使用一些插件,但是那些東西都是直接寫(xiě)UTF-8碼的,有時(shí)候反倒不方便,不過(guò)以后任務(wù)量巨大的時(shí)候可能會(huì )考慮使用。Bat文件內容: set path=%path%;%
JAVA_HOME%/bin/,native2ascii -encoding UTF-8 ApplicationResources_bk.txt > ApplicationResources_zh.properties
PS:上面的方法好老了,實(shí)際操作起來(lái)相當麻煩,現在基本都是使用Eclipse插件,Eclipse3.1時(shí)使用PropertyEditor,但是這 個(gè)項目看上去好像停擺了,到Eclipse3.2時(shí)改用了ResourseBundle,相當的強勁的一個(gè)插件,推薦使用。
5.
GET請求
亂碼
如果在本項目中采用了
get方式提交請求并附加參數,結果導致編碼
亂碼,原因是Tomcat默認請求編碼是ISO8859,需要在Tomcat的配置文件 server.xml添加一個(gè)參數,URIEncoding=”UTF-8”,這樣請求中附件的參數就會(huì )以UTF-8來(lái)進(jìn)行編碼。
6.Ajax請求
亂碼
使用Ajax,JS也是默認使用ISO8859編碼,所以在進(jìn)行請求時(shí)遇到中文參數需要進(jìn)行編碼,如:var url = "
GetSelectListAction.do?queryData=subTrade" + "&queryId=" + encodeURI(obj.value) + "&r=" + Math.random();
這里有兩個(gè)地方需要注意:第一個(gè)地方是encodeURI(),方法,可以將參數進(jìn)行轉碼,默認是轉化為UTF-8,如果需要轉為其他碼制,需要在方法中添加第二個(gè)參數。
第二個(gè)地方是Math.random(),由于A(yíng)jax有緩存機制,在接受請求的時(shí)候第一時(shí)間先判斷該請求的地址是否被訪(fǎng)問(wèn)過(guò),如果被訪(fǎng)問(wèn)過(guò)則 直接使用緩存中的內容返回,這個(gè)東西很討厭,客戶(hù)在訪(fǎng)問(wèn)過(guò)一次出錯后以后每次出現的都是這個(gè)錯誤,所以在請求中給其增加一個(gè)時(shí)間戳,只要可以隨機生成一個(gè) 不同的字串就可以,保證Ajax每次都去訪(fǎng)問(wèn)服務(wù)器。
7.
GET方法的另一個(gè)
亂碼問(wèn)題
在項目即將交工的時(shí)候突然又出現
亂碼問(wèn)題,發(fā)現對于超長(cháng)的漢字做為參數傳遞仍然會(huì )出現
亂碼問(wèn)題,解決方法是采用
java.net.URLEncoder的 Encode方法強制轉碼,缺點(diǎn)是會(huì )使JSP頁(yè)面代碼相當的長(cháng),但是目前還沒(méi)有其他好的解決辦法,我想最好的辦法就是不用中文做為參數傳遞 :P,寫(xiě)法如:<a href="TestAction.do?name=<%=
java.net.URLEncoder.encode("你好","UTF-8")%>
8.
亂碼仍然是偶們的心病,一直牽動(dòng)著(zhù)大家的心,最近一位朋友說(shuō)連接MSSQL數據庫有
亂碼,使用了很多辦法,都沒(méi)解決,后來(lái)重新下了個(gè)新的驅動(dòng)搞定……
數據庫
亂碼其實(shí)也很討厭的,一般來(lái)說(shuō)驅動(dòng)問(wèn)題比較常見(jiàn),所以一旦碰到比較難纏的
亂碼可以先考慮下?lián)Q換驅動(dòng)。也有如MySQL這種,直接連接的時(shí)候就需要顯示進(jìn)行編碼轉化的,這個(gè)就要不同情況區別對待了。
//2007年11月30日添加
9.WebService
亂碼,由于對WebService不怎么熟悉,使用的是Weblogic提供的WebService支持,
亂碼再次出現搞得手忙腳亂,而且無(wú)從下手,在自己系統上跑都沒(méi)有問(wèn)題,結果跑到服務(wù)器上就全亂套,又無(wú)法調試,愁人。
反復嘗試的過(guò)程就不說(shuō)了,絕對比普通的Web開(kāi)發(fā)麻煩的多。最終解決方法:
A.為WebService服務(wù)也加上一個(gè)filter,WebService也是走HTTP協(xié)議的,這個(gè)東西同樣有用,先得加上。
B.修改服務(wù)器上的環(huán)境變量,LANG=zh_CN.UTF-8,改成這個(gè)是為什么我仍然說(shuō)的不是很清楚,不過(guò)當時(shí)開(kāi)發(fā)人員就是在Win下開(kāi)發(fā)的,我在自己的Ubuntu上測試沒(méi)問(wèn)題,拿到Redhat服務(wù)器上就不行,因為服務(wù)器上默認的是LANG=en_US.UTF-8,這個(gè)明顯是不支持漢字的。
經(jīng)過(guò)這兩個(gè)步驟WebService
亂碼總算得到抑制,它主要的麻煩在于所有與協(xié)議有關(guān)的東西都被Weblogic包辦,里面做什么事情我們不好控制,所以只能采取這種比較笨的辦法,雖然解燃煤之急但無(wú)法尋根溯源的搞定它,說(shuō)不定哪天又會(huì )出來(lái)搞鬼。果然又一次出現
亂碼問(wèn)題,經(jīng)過(guò)比較環(huán)境變量發(fā)現服務(wù)器上的LC_CTYPE被修改了,所以強制改成LC_CTYPE=zh_CN。修改環(huán)境變量的方法不到萬(wàn)不得已不推薦使用。