URL傳值中文亂碼的解決


使用 tomcat 時,相信大家都回遇到中文亂碼的問題,具體表現為通過表單取得的中文數據為亂碼。

一、初級解決方法 通過一番檢索后,許多人采用了如下辦法,首先對取得字符串按照 iso8859-1 進行解碼轉換,然后再按照 gb2312 進行編碼,最后得到正確的內容。

示例代碼如下:

http://xxx.do?ptname='我是中國人'

String strPtname = request.getParameter("ptname");

strPtname = new String(strPtname.getBytes("ISO-8859-1"), "UTF-8");

String para = new String( request.getParameter("para").getBytes("iso8859-1"), "gb2312");

具體的原因是因為美國人在寫 tomcat 時默認使用 iso8859-1 進行編碼造成的。

然而,在我們的 servlet 和 jsp 頁面中有大量的參數需要進行傳遞,這樣轉換的話會帶來大量的轉換代碼,非常不便。

二、入門級解決方法 后來,大家開始寫一個過濾器,在取得客戶端傳過來的參數之前,通過過濾器首先將取得的參數編碼設定為 gb2312 ,然后就可以直接使用 getParameter 取得正確的參數了。這個過濾器在 tomcat 的示例代碼 jsp-examples 中有詳細的使用示例, 其中過濾器在 web.xml 中的設定如下,示例中使用的是日文的編碼,我們只要修改為 gb2312 即可 view plaincopy to clipboardprint? Set Character Encoding filters.SetCharacterEncodingFilter encoding EUC_JP Set Character Encoding filters.SetCharacterEncodingFilter encoding EUC_JP

過濾器的代碼如下:

view plaincopy to clipboardprint?

public class SetCharacterEncodingFilter implements Filter

{ // 編碼的字符串

protected String encoding = null; // 過濾器的配置

protected FilterConfig filterConfig = null; // 是否忽略客戶端的編碼

protected boolean ignore = true; // 銷毀過濾器

public void destroy(){

this.encoding = null;

this.filterConfig = null; }

// 過濾方法

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

// 如果使用過濾器,忽略客戶端的編碼,那么使用通過過濾器設定編碼

if (ignore || (request.getCharacterEncoding() == null))

{ String encoding = selectEncoding(request);

if (encoding != null)

request.setCharacterEncoding(encoding); }

// 傳送給下一個過濾器

chain.doFilter(request, response); }

// 初始化過濾器

public void init(FilterConfig filterConfig) throws ServletException {

this.filterConfig = filterConfig;

this.encoding = filterConfig.getInitParameter("encoding");

String value = filterConfig.getInitParameter("ignore");

if (value == null)

this.ignore = true;

else if (value.equalsIgnoreCase("true"))

this.ignore = true;

else if (value.equalsIgnoreCase("yes"))

this.ignore = true; else this.ignore = false; }

// 返回過濾器設定的編碼

protected String selectEncoding(ServletRequest request)

{ return (this.encoding); } }

public class SetCharacterEncodingFilter implements Filter{

// 編碼的字符串

protected String encoding = null; // 過濾器的配置

protected FilterConfig filterConfig = null; // 是否忽略客戶端的編碼

protected boolean ignore = true; // 銷毀過濾器

public void destroy() {

this.encoding = null;

this.filterConfig = null; }

// 過濾方法

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

// 如果使用過濾器,忽略客戶端的編碼,那么使用通過過濾器設定編碼

if (ignore || (request.getCharacterEncoding() == null))

{ String encoding = selectEncoding(request);

if (encoding != null) request.setCharacterEncoding(encoding); }

// 傳送給下一個過濾器

chain.doFilter(request, response); }

// 初始化過濾器

public void init(FilterConfig filterConfig) throws ServletException {

this.filterConfig = filterConfig;

this.encoding = filterConfig.getInitParameter("encoding");

String value = filterConfig.getInitParameter("ignore");

if (value == null) this.ignore = true;

else if (value.equalsIgnoreCase("true")) this.ignore = true;

else if (value.equalsIgnoreCase("yes")) this.ignore = true;

else this.ignore = false; }

// 返回過濾器設定的編碼

protected String selectEncoding(ServletRequest request)

{ return (this.encoding); } }

 

然而在 tomcat5 中,即使使用過濾器,仍然可能取得亂碼,原因何在呢?

三、高級解決方法

這是因為,在 tomcat4 和 tomcat5 中對參數的處理是不一樣的,在 tomcat4 中 get 與 post 的編碼是一樣的,所以只要在過濾器中通過 request.setCharacterEncoding 設定一次就可以解決 get 與 post 的問題。

然而,在 tomcat5 中,get 與 post 的處理是分開進行的 在 tomcat 5 中,為了解決編碼問題,tomcat 的作者作了很多努力,具體表現為在 tomcat 的配置文件 server.xml 中對 Connector 元素增加了如下的配置參數,專門用來對編碼進行直接的配置 URIEncoding 用來設定通過 URI 傳遞的內容使用的編碼,tomcat 將使用這里指定的編碼對客戶端傳送的內容進行編碼。

什么是 URI 呢?

java doc 的說明中如下說明:URI 是統一資源標識符,而 URL 是統一資源定位符。

因此,籠統地說,每個 URL 都是 URI,但不一定每個 URI 都是 URL。這是因為 URI 還包括一個子類,即統一資源名稱 (URN),它命名資源但不指定如何定位資源。 也就是說,我們通過 get 方法提交的參數實際上都是通過 uri 提交的,都由這個參數管理,如果沒有設定這個參數,則 tomcat 將使用默認的 iso8859-1 對客戶端的內容進行編碼。 useBodyEncodingForURI 使用與 Body 一樣的編碼來處理 URI, 這個設定是為了與 tomcat4保持兼容,原來在 tomcat4 和 tomcat5 中隊參數的處理是不一樣的,在 tomcat4 中 get 與 post 的編碼是一樣的,所以只要在過濾器中通過 request.setCharacterEncoding 設定一次就可以解決 get 與 post 的問題。

然而,在 tomcat5 中,get 與 post 的處理是分開進行的,對 get 的處理通過 前面的 URIEncoding 進行處理,對 post 的內容依然通過 request.setCharacterEncoding 處理,為了保持兼容,就有了這個設定。 將 useBodyEncodingForURI 設定為真后,就可以通過 request.setCharacterEncoding 直接解決 get 和 post 中的亂碼問題。 這樣,我們可以通過在 server.xml 中設定 URIEncoding 來解決 get 方法中的參數問題,使用過濾器來解決 post 方法中的問題。 或者也可以通過在 server.xml 中設定 useBodyEncodingForURI 為 true ,配合過濾器來解決編碼的問題。 在這里,我強烈建議在網站的創作過程中,全程使用 utf-8 編碼來徹底解決亂碼問題。

 

具體操作如下:

1、頁面內容使用 utf-8 格式保存,在頁面中加入

<mete http-equiv="contentType" content="textml;charst=utf-8">

 

2、服務器端的 server.xml 中設定 useBodyEncodingForURI = true

3、使用過濾器,過濾器設定編碼為 utf-8

四:如果有一些轉碼也轉不過來的話,可是試試打開tomcat的server.xml,找到並在最后加上useBodyEncodingForURI="true" URIEncoding="UTF-8",如下

<Connector acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" port="80" redirectPort="8443"  useBodyEncodingForURI="true" URIEncoding="UTF-8">

 

五: 如果用jstl的話,可以自己寫一個el的function,調用URLEncoder.encode來編碼。

IE缺省對URL后面的參數是不編碼發送的,但是tomat缺省是按ISO8859-1來進行URL解碼,因此才會出現上述錯誤。好的做法是:

1、在URL參數中確保用UTF-8編碼之,方法可以用js函數encodeURI(),或調用自定義的el function;

2、設置server.xml中的Connector熟悉URIEncoding="UTF-8",確保解碼格式與編碼格式統一;

方法四: view plaincopy to clipboardprint?

在action中,String s=request.getParameter("s"); s=new String(s.getBytes("iso-8859-1"),"gbk");

六:js的亂碼解決

1.客戶端: url=encodeURI(url);

服務器: String linename = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");

2.客戶端: url=encodeURI(encodeURI(url)); //用了2次encodeURI

服務器: String linename = request.getParameter(name); //java : 字符解碼

linename = java.net.URLDecoder.decode(linename , "UTF-8");


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM