今天碰到一個問題,在Controller類中一個方法跳轉到該類中的另一個方法,帶着中文參數,在跳轉之前對該參數進行編碼:
msg = java.net.URLEncoder.encode(msg,"UTF-8"); ResponseData response = new ResponseData("redirect:/service/mxgl/"+typeid+"/"+cube.getDstype()+"/mxs?msg="+msg);
在另一個方法里接收該參數:
String msg = request.getParameter("msg"); if( msg != null){ msg = java.net.URLDecoder.decode(msg,"UTF-8"); view.addObject("msg",msg); }
結果在前台顯示亂碼,百思不得其解,遂百度,終於知道原因:原來在服務器端用request.getParameter("msg")獲取參數之前會自動做一次解碼的工作,而且是默認的ISO-8859-1,相當於調用了一次java.net.URLDecoder.decode(msg, "ISO-8859-1"),難怪有亂碼,這就相當於:
public static void main(String[] args) throws UnsupportedEncodingException { String name="測試"; //UTF-8編碼
name=java.net.URLEncoder.encode(name,"UTF-8"); System.out.println(name); //ISO-8859-1解碼
name=java.net.URLDecoder.decode(name, "ISO-8859-1"); System.out.println(name); //UTF-8解碼
System.out.println(java.net.URLDecoder.decode(name, "UTF-8")); }
結果:
解決方案是對要傳的中文參數進行兩次編碼,這就相當於:
public static void main(String[] args) throws UnsupportedEncodingException { String name="測試"; //UTF-8編碼
name=java.net.URLEncoder.encode(name,"UTF-8"); System.out.println(name); //UTF-8編碼
name=java.net.URLEncoder.encode(name,"UTF-8"); System.out.println(name); //ISO-8859-1解碼
name=java.net.URLDecoder.decode(name, "ISO-8859-1"); System.out.println(name); //UTF-8解碼
System.out.println(java.net.URLDecoder.decode(name, "UTF-8")); }
結果:
這樣就解決了亂碼問題。另外你可能有個疑問,為什么用UTF-8編碼兩次,然后分別用ISO-8859-1和UTF-8解碼沒問題呢?不應該是UTF-8解碼兩次無亂碼問題嗎?那是因為第一次編碼后將漢字編碼為%和字母數字的格式,而第二次編碼的時候是對%和字母數字進行編碼,雖然解碼的時候使用的是ISO-8859-1,但是對於%和字母數字而言用ISO-8859-1和UTF-8解碼出來的是一樣的,此時就回到了漢字被編碼過一次的字符串了,當再次進行解碼的時候使用UTF-8就回將它轉會漢字。