My Calendar

2015年2月4日 星期三

中文編碼處理

中文編碼處理

當 Servlet 需要處理中文字時,那 Servlet 應該如何處理請求參數才能得到正確的中文字 ? 在編碼處理上基本有兩種情況處理分別是 GET 和 POST。

POST 請求參數編碼處理
如果客戶端沒有透過 Content-Type 設定編碼資訊 ( charset=UTF-8 ),那 HTTPServletRequest 的 getCharacterEncoding() 回傳值將會是 null,這時候容器將會使用預設編碼( ISO-8859-1 ) 處理,如果客戶端透過 UTF-8 發送非 ASCII 的請求參數,而 Servlet 直接使用 getParameter() 取得參數值,就會得到不正確的結果。

要正確的顯示中文字那可以使用 HttpServletRequest 的 setCharacterEncoding() 指定 POST 請求參數時使用的編碼。一定要在取得任何請求參數前執行 setCharacterEncoding() 才有作用。

GET 請求參數編碼處理
如果請求參數是以 GET 的方式傳遞那要處理 UTF-8 的編碼該如何呢? 我相信到這很多人應該會說用 setCharacterEncoding() 吧。那 setCharacterEncoding() 就能正確的處理中文字元嗎? 答案是 NO! NO! NO! ( 很重要所以說三次 ) 。在 API 文件對這個方法的定義以經說明清楚。

Overrides the name of the character encoding used in the body of this request

表示這方法只能在請求參數使用 POST 傳遞才有效(在 Tomcat 預設和沒有修改設定的情況). 既然 setCharacterEncoding() 不能對 GET 的請求參數進行處理 , 那還有其它方法處理嗎 ? 另外一個編碼的處理方式, 則透過 String 的 getBytes() 指定編碼取得 bytes array 在透過 String 重新建構正確的編碼.

例如瀏覽器使用 UTF-8 處理字元, Web Container 預設使用 ISO-8859-1 編碼, 正確處理編碼的方式是:
String name = request.getParameter("uname");
name = new String(name.getBytes("ISO-8859-1"),"UTF-8");

以下有一範例:

建立表單分別使用 GET 和 POST
<!DOCTYPE HTML>
<html>
<head>
<title>form_get</title>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
</head>
<body>
<FORM method="post" action="encoding">
  user : <input type = "text" name = "uname"><br><br>
  <button type="submit">Submit</button>
</FORM>
</body>
</html>

分別處理 GET 和 POST 編碼的 Servlet 如下:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(/encoding)
public class EncodingDemo extends HttpServlet {
 private static final long serialVersionUID = 1L;
       
    public EncodingDemo() {
        super();
    }

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  String name = request.getParameter("uname");
     name = new String(name.getBytes("BIG5"),"BIG5");
  System.out.println(name);
  
 }

 
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  request.setCharacterEncoding("BIG5");
  String name = request.getParameter("uname");
  System.out.println(name);
 }

}

沒有留言:

張貼留言