1. 程式人生 > >GET請求的中文亂碼問題及處理意義

GET請求的中文亂碼問題及處理意義

首先看一段亂碼的程式:
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {   //0設定編碼   request.setCharacterEncoding("UTF-8");   String username=request.getParameter("username");   String password=request.getParameter("userPwd");   System.out.println("處理之前:"+username+":"+password);  //此時輸出的結果:處理之前:胡玉勉:aa1234bb---也就是說中文字元本身的編碼還是不對。
  //做如下處理:   username = new String(username.getBytes("ISO8859-1"),"UTF-8");   System.out.println("處理之後:"+username+":"+password);   response.setContentType("text/html;charset=UTF-8");   ServletOutputStream out=response.getOutputStream();   out.println(username);   out.println(password);  }
亂碼原因的分析: get請求的原理圖:
1.資料解析編碼:指的是html頁面form表當資料提交時候的編碼方式,這個編碼方式和頁面編碼是統一的,這裡設定為UTF-8 2.GET請求的的請求資料,並不在請求體體中,而是在請求行中的?之後。而整個請求資料,包括請求行,請求頭,請求體都會通過http協議傳送到服務端去處理。(HTTP協議時不支援中文的,預設編碼:ISO8859-1)
對比post請求,post請求的的請求資料都包含在請求體中,當傳送了了服務端的時候,通過設定request.setCharacterEncoding("UTF-8"),就能夠使得資料傳輸到服務端的時候,能夠將其解析成utf-8的資料。 但是,這樣的設定編碼的操作對請求行中的資料缺失無效的。
3.前面說了資料時通過http協議的方式傳送到服務端,而請求行的資訊(原始狀態下是UTF-8編碼)經過http協議進行傳輸的時候,http協議對其進行了預設編碼的編碼操作。併發送到了服務端,而服務端類似post請求的處理方式,對其有沒有作用。 那麼,服務段應該如何對這樣的亂碼,就行解碼,讓其還原成UTF-8編碼呢。實際上就是還原成原始資料的編碼? (亂碼產生的核心本質:源編碼和讀取顯示的編碼不一致) 思路:找到源編碼的二進位制,然後重新用UTF-8進行解碼就可以了。 4.解決辦法: 服務端:String username=request.getParamter("username");----這是獲得的ISO8859-1編碼的亂碼資料
解碼:
username.getBytes("ISO8859-1");-----這樣就獲得了原始資料。
而原始資料就是按照UTF-8編碼的,那麼此時,只需要將其變成UTF-8的字串資料就ok
new String(username.getBytes("ISO8859-1,"UTF-8""));
最終表現在上面的程式中,值處理之前,是亂碼的,通過解碼在還原的操作,中文則不再亂碼。 仍然存在的疑惑: 1. response.setContentType("text/html;charset=UTF-8"); 如果沒有手動解碼的程式碼username.getBytes("ISO8859-1"); 通過上述方式設定response編碼,將其傳送到瀏覽器,沒有出現亂碼。 這種情形是合理的嗎?是不是上述操作的底層也是用過來類似 username.getBytes("ISO8859-1") 這樣的解碼方式?(可以這麼理解) 2.如果是post請求的時候,請求內容在請求體中,不也要通過http協議對其進行編碼嗎?為什麼資料傳送到服務端,就直接可以通過 request.setCharcterEncoding(UTF-8)對資料進行解碼?(視訊裡面提到流的處理方式) 這裡面,request.setCharacterEncoding(UTF-8)值能請求體中的流進行處理。 那麼這個還有一個問題就是,   response.setContentType("text/html;charset=UTF-8");   ServletOutputStream out=response.getOutputStream();   out.println(username);   out.println(password); 做了這樣的操作以後,即使沒有手動解碼,在服務端通過上述流操作,將資料輸出到瀏覽器中,沒有出現亂碼。 那麼對於get請求,手動解碼的意義是什麼呢。後來明白了,因為大多數情況下,還是要將資料資訊儲存到資料庫中個, 儲存到資料庫的操作,可不是流的操作, 那麼這個時候,如果這屆儲存到資料庫的情況下,就會亂碼的。所以通過手動解碼的方式的意義還是大大的。 當然,一般不用位元組流來處理文字資料,上述程式碼,改成response.getWriter的方式處理就ok。