中文編碼處理
當 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 編碼, 正確處理編碼的方式是:
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); } }
沒有留言:
張貼留言