今天在用jquery的$.ajax方法做非同步互動時遇到很蛋疼的中文亂碼問題,折騰了好幾個小時,終於解決了。現在我就詳細地說明一下問題的解決經過。
我的最終代碼如下:
程式碼片段一:(getResultServlet.java)
public static String decodeJqueryAjaxStr(String str){if(str==null || str.equals("")){return "";}str = str.trim();try {str = java.net.URLDecoder.decode(str, "utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return str;}
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");request.setCharacterEncoding("UTF-8");PrintWriter out;out=response.getWriter();//String text=decodeJqueryAjaxStr(request.getParameter("mytxt"));String text=request.getParameter("mytxt");//String text = new String(str.getBytes("ISO-8859-1"),"UTF-8");try {JSONArray jsnarray = new JSONArray(); //定義JSON數組ArrayList<Questions> questions=questionDao.getInfoByName(text);if (questions==null||questions.size()==0) {JSONObject obj = new JSONObject();obj.put("trunk", "不存在相關的題目資訊!");obj.put("aopt", ""); obj.put("bopt", "");obj.put("copt", "");obj.put("dopt", "");obj.put("ropt", "");jsnarray.add(obj);}else {for (int i = 0; i < questions.size(); i++) {JSONObject obj = new JSONObject();Questions tmpQuestions=questions.get(i);obj.put("trunk", tmpQuestions.getTrunk());obj.put("aopt", tmpQuestions.getAopt());obj.put("bopt", tmpQuestions.getBopt());obj.put("copt", tmpQuestions.getCopt());obj.put("dopt", tmpQuestions.getDopt());obj.put("ropt", tmpQuestions.getRopt());jsnarray.add(obj);}}out.println(jsnarray); out.flush();out.close();} catch (Exception e) {e.printStackTrace();}}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}
程式碼片段二(javascript代碼):
function getinfolist(query){if(query==""){alert("請輸入查詢條件。");return;}$.ajax({url:"/taobaoexam/servlet/getResultServlet",type:"post",dataType: "json", data:"mytxt="+query,beforeSend:function(XMLHttpRequest){$("#info").empty();var $htmlLi = $("<a id='loading' style='background-color:#FFFFCC'>資訊載入中...</a>"); //建立DOM對象 $("#info").append($htmlLi);},success:function(data,textStatus){$("#info").empty();$("#info").css({"font-size":"12px"});//請求成功$(data).each(function(){var $htmlLi = $("<hr/><a style='background-color:#FFFFCC'>"+this.trunk+"</a>"); //建立DOM對象 var $htmlLi1 = $("<br/><a>"+this.aopt+"</a>"); var $htmlLi2 = $("<br/><a>"+this.bopt+"</a>"); var $htmlLi3 = $("<br/><a>"+this.copt+"</a>"); var $htmlLi4 = $("<br/><a>"+this.dopt+"</a>"); var $htmlLi5 = $("<br/><a style='background-color:#FFFFCC'>正確答案:"+this.ropt+"</a>"); $("#info").append($htmlLi); $("#info").append($htmlLi1); $("#info").append($htmlLi2); $("#info").append($htmlLi3); $("#info").append($htmlLi4); $("#info").append($htmlLi5);});},error:function(XMLHttpRequest,textStatus,errorThrown){$("#info").empty(); var $htmlLi = $("<a style='background-color:#FFFFCC'>頁面載入失敗,請稍後重試。</a>"); //建立DOM對象 $("#info").append($htmlLi);},complete:function(XMLHttpRequest,textStatus){}});}
我一開始用的get方法,在本地測試通過了,不會出現中文亂碼問題,但是放到伺服器上就不行了,很是鬱悶。當時的代碼是這樣的:
javascript中:
url:"/taobaoexam/servlet/getResultServlet",type:"get",dataType: "json", data:"mytxt="+encodeURIComponent(query),
getResultServlet.java中:
response.setContentType("text/html;charset=utf-8");request.setCharacterEncoding("UTF-8");PrintWriter out;out=response.getWriter();String text=decodeJqueryAjaxStr(request.getParameter("mytxt"));//String text=request.getParameter("mytxt");//String text = new String(str.getBytes("ISO-8859-1"),"UTF-8");
跟上面的代碼比較,大家可以發現不同之處,一開始我用的是get方法,在javascript端用encodeURIComponent方法對中文字元進行編碼,然後在getResultServlet.java檔案中,用java.net.URLDecoder.decode對傳過來的已編碼的中文字元進行解碼。本地測試通過,伺服器不行,到現在還不明白問題到底出在哪兒,還請高手不吝賜教。
之後,我改成post方法,將各部分的編碼都設為utf-8就可以了。
參考內容如下:
[java] view plain copy <%@ page language="java" pageEncoding="UTF-8"%> <%@ page contentType="text/html;charset=utf-8"%> <html> <head> <title>亂碼</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> </head> <body> 必須的!亂碼 </body> </html>
這個亂碼問題是最簡單的亂碼問題。就是頁面編碼不一致導致的亂碼。
注意這個頁面有三個部分涉及到了編碼的設定:
第一處的編碼格式為jsp檔案的儲存格式。Ecljpse會根據這個編碼格式儲存檔案。並編譯jsp檔案,包括裡面的漢字。
第二處編碼為解碼格式。必須與第一處一致,必須的。第二處所在的這一行,預設是使用iso8859-1的編碼格式。所以如果沒有這一行的話,也會出現亂碼。必須一致才可以。
第三處編碼為控制瀏覽器的解碼方式。如果前面的解碼都一致並且無誤的話,這個編碼格式沒有關係。有的網頁出現亂碼,就是因為瀏覽器不能確定使用哪種編碼格式。因為頁面有時候會嵌入頁面,導致瀏覽器混淆了編碼格式。出現了亂碼。
第二種:GET和POST傳參時出現亂碼。
這個亂碼也是tomcat的內部編碼格式iso8859-1在搗亂,也就是說post提交時,如果沒有設定提交的編碼格式,則會以iso8859-1方式進行提交,接受的jsp卻以utf-8的方式接受。導致亂碼。既然這樣的原因,下面有幾種解決方式,並比較。
A、GET請求參數處理
String str = new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8") ; 這樣的話,每一個參數都必須這樣進行轉碼。很麻煩。但確實可以拿到漢字。
B、POST請求參數處理
在處理請求頁面上開始處,執行請求的編碼代碼,request.setCharacterEncoding("UTF-8"),把提交內容的字元集設為UTF-8。使用String str = request.getParameter("something");即可得到漢字參數。但每頁都需要執行這句話。
我的情況屬於第二種,因為用Ajax提交請求,所以傳遞的參數都是按照Ajax的標準來編碼的。Ajax的post方式,預設使用utf-8的編碼提交參數的,所以要把Ajax的Content-Type要求標頭設定"application/x-www-form-urlencoded;charset="utf-8",以此來通知伺服器,用戶端發送參數所使用的編碼。這樣,伺服器端可以直接通過String word = request.getParameter("something");來擷取經過轉碼後的參數值,省去了request. setCharacterEncoding。當然,也可以在處理請求的Servlet中的doPost方法中加上request.setCharacterEncoding("UTF-8"),達到的效果是相同的。
參考資料來源:http://blog.csdn.net/kaihua_86/article/details/6025984