關於JAVA中文亂碼(1)

編程,讓人無語的就是,業務邏輯都寫好了,什麼都弄好了,可是亂碼出現了。研究亂碼的這一段時間,讓我也有了一點點對處理亂碼的心得。如今,我來講說我對亂碼的見解。javascript

亂碼案例

前臺-jsp(utf-8):

<form action="相應的action" method="@"><input name="test" value="測試" type="submit"/>
複製代碼

後臺-servlet :

若是@=post:html

複製代碼

doPost(...){System.out.println(request.getparameter("test")); //顯示的是???è??,亂碼出現 System.out.println(request.getQueryString()); //顯示null,無值java

> 若是@=get:  
> >```java
doGet(...){System.out.println(request.getparameter("test"));    //顯示的是???è??,亂碼出現
System.out.println(request.getQueryString());    //顯示test=%E6%B5%8B%E8%AF%95,獲取到編碼後的test
複製代碼

分析問題

由上能夠看出幾點:web

  1. post提交時,request.getQueryString()方法獲取不到值,只有get提交才行。
  2. jsp向後臺提交數據,自動進行所設置的編碼格式進行編碼。所以後臺獲取的都是編碼好的數據,如get提交時,地址欄的顯示便可印證:http://10.110.10.11:8080/test1/test?test=測試。

那我就要說道說道了,test傳到後臺是%E6%B5%8B%E8%AF%95,爲何request.getparameter("test")獲取到的倒是???è??呢? 那是由於request方法獲取值時,會自動進行一次解碼工做,並且是默認的ISO-8859-1(可設置request.setCharacterEncoding("utf-8")改變默認的ISO-8859-1)。ajax

亂碼解決

那麼,如何獲取正確格式的數據呢?一樣分兩種:編程

若是@=post:json

request.setCharacterEncoding("utf-8"); //輸出時顯示的是 測試。bash

若是@=get:異步

request.setCharacterEncoding("utf-8"); //輸出時顯示的還是 ???è??。jsp

由上能夠看出:

  1. post提交,只需調用getparameter以前,設置request.setCharacterEncoding("utf-8");便可避免亂碼。post提交所以十分方便,不容易出現亂碼,因此咱們重點是說說get提交!
  2. get提交,以上方法就然並卵了。那麼,若是咱們用java.net.URLDecoder.decode(String,"utf-8");進行utf-8解碼呢?
System.out.println(java.net.URLDecoder.decode(request.getparameter("test"), "utf-8"));
複製代碼

直接輸出結果怎樣,結果任然是???è??。爲何呢?由於前面已經說了jsp向後臺提交數據自動進行一次編碼,而request.getparameter("test")的方法,會自動作一次解碼的工做,所以以上方法進行解碼是解碼了兩次:request解碼一次,URLDecoder解碼一次!印證該觀點很簡單:

System.out.println(request.getparameter("test"));  //輸出???è??,進行了一次解碼
System.out.println(java.net.URLDecoder.decode("??è??","utf-8"));  //輸出 ??è??,也看出了當對一個已編碼的數據重複解碼時,仍然解出的是同樣的。
複製代碼

既然都知道了緣由,那就知道解決辦法了,既然前臺編碼一次,後臺用request.getparameter("test "),並設置request解碼方式爲utf-8在get提交裏面行不通,那咱們就在前臺編碼兩次唄,而以上URLDecoder解碼反正不就是解碼了兩次麼。前臺進行第二次編碼: jsp:

<!--超連接 href也能夠寫一個Action,後臺web.xml或者Struts.xml能攔截到就行。 對錶單的編碼,等之後找到方法了再加進來。-->
<a href="test2.jsp?url=<%=java.net.URLEncoder.encode(String,"utf-8")%>">進行編碼</a>
複製代碼

js:

window.open(url+"?name="+encodeURI(encodeURI(document.getElementByName("name").value)));
複製代碼

記住:要想用JS實現jsp的java.net.URLEncoder.encode必須用兩次編碼:encodeURI(encodeURI(str));,由於js不會像jsp同樣自動進行一次編碼。後臺使用System.out.println(java.net.URLDecoder.decode(request.getparameter("test"), "utf-8"));能夠輸出"測試"。

其實,像這樣前面兩次,後面兩次的,真的很麻煩。有人問了,還有沒有什麼簡單一點的辦法啊?---辦法嘛,仍是有的,那就是在前臺不作任何處理的狀況下,後臺只需用如下代碼便可實現get提交亂碼問題(post提交,一樣有效):

String name =new String(request.getParameter("test").getBytes("iso8859-1"),"utf-8"); //意思就是new一個String,把request解碼後的String轉換成utf-8。嗯,這個是轉換,不是第二次解碼了。
System.out.println(name);//輸出"測試" 
複製代碼

一個完美解決亂碼的辦法,又有人說了,那你直接拿出最後一個辦法就好了嘛,前面說一大堆幹嗎,我只想說五個字:讓我裝個逼! 哈哈,開個玩笑,其實否則,有時我寫代碼時,發現這個萬能辦法有時也無論用,後臺仍然是亂碼,具體是爲何,我也不知道,問題涉及得過高深,我還不懂,只能繼續學習強化本身了。還有就是,好比,你用ajax實現異步刷新頁面,提交的時候那必定是js提交吧,對於json的編碼,你還不是要用到先前的辦法。

相關文章
相關標籤/搜索