Java 編碼問題總結
一、實踐原則
1、頁面檔案的儲存格式做到與聲明一緻
如聲明<%@ page language="java" pageEncoding="utf-8"%>,則該檔案儲存為utf-8格式
2、無論是Get、Post還是JavaScript直接調用,浏覽器以頁面檔案指定的編碼格式送出請求
3、JavaScript的方法如encodeURI、encodeURIComponent等使用utf-8格式編碼資料
二、Http協定和Servlet規範
A、Http協定
1、Get 根據Http協定,Get方法中的uri、queryString等均為iso-8859-1編碼格式
2、Post Post方法中可以使用其他的編碼格式,如utf-8,預設為iso-8859-1
B、Servlet規範
1、ServletRequest
void setCharacterEncoding(String env); 該方法可以用于指定request body中資料的編碼格式,Container根據此格式解析
注:該方法必須在取參數及擷取輸入流之前調用,否則無效,即getParamater(String key)和getReader()之前調用
2、ServletResponse
void setCharacterEncoding(String charset);該方法用于設定Container響應輸出流的編碼格式,但不指定響應内容格式,Servlet2.4+支援
void setContentType(String type);該方法用于指定響應内容格式,同時可以指定響應輸出流格式,如下兩種情況基本等效,不同在于使用A時,浏覽器将使用預設編碼,B将告訴浏覽器使用指定編碼:
A、setCharacterEncoding("utf-8"); setContentType("text/html");
B、setContentType("text/html; charset=UTF-8");
以上方法可以重複調用覆寫以前設定,但應該在輸出之前,如調用getWriter();之前
三、伺服器狀況
目前的不少伺服器對Servlet規範中 void setCharacterEncoding(String env);支援的不夠好,畢竟國外廠商本語是English,可能沒有實作該方法,即使調用了改方法,仍然使用預設的iso-8859-1解析
個人測試了如下伺服器支援:
A、Apache-Tomcat-5.5.12
B、Apache-Tomcat-6.0.18
四、方案總結
A、統一編碼方式,如使用utf-8,在伺服器端用指定的編碼格式解析資料(如果容器不支援,則手工轉碼),然後再指定輸出格式
B、将要送出的英文以外格式的參數先進行轉碼再送出,如encodeURIComponent,伺服器端通過URIDecoder解碼(utf-8格式),處理完成後,或者指定輸出流及内容格式為utf-8,或者轉為gb2312,以iso-8859-1送回