1. 程式人生 > >tomcat字符集與中文亂碼的解決

tomcat字符集與中文亂碼的解決

如果你搞Java web,相信你一定遇到過亂碼問題!

通常,你是否是這樣處理中文傳參的呢?

前臺:

url=encodeURI(url);
後臺:
String name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");

頁面:一通UTF-8或GB2312設定編碼。

tomcat:統一UTF-8.

然後部署測試發現,亂碼啊,你怎麼還在糾纏著我!我又不是唐僧,身上更沒肉!

亂碼問題,是個臭蟲!很臭的臭蟲!我也遇到過多次,每次都是很糾結,每次都是經過一番轉換,然後信誓旦旦地告訴自己和同事,這個亂碼我給解決了!有一天,在郵箱裡發現測試部提交了一個BUG,說日誌裡怎麼全部是亂碼~~~這時候同事們都朝我望過來,我只能滿臉黑線|||

最近閒暇下來,看了一些文章,也總結了一些,這裡還是比較推崇下面要貼的內容(因為主體還是別人的內容,暫且標為轉帖更確切!)。我不清楚亂碼問題是否已經根除了,但是我知道現在2輪測試的過程中,再也沒有了亂碼的蹤影,也許她真得消失了?!!我不知道。

好吧,進入內容吧:

=========================================咯咯================================

使用 tomcat 時,相信大家都回遇到中文亂碼的問題,具體表現為
1)通過表單取得的中文資料為亂碼
2)頁面提交中文資料,伺服器端接收為亂碼
 
一、初級解決方法 
通過一番檢索後,許多人採用瞭如下辦法,首先對取得字串按照 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?
<filter>    
<filter-name>Set Character Encoding</filter-name>    
<filter-class>filters.SetCharacterEncodingFilter</filter-class>    
<init-param>    
<param-name>encoding</param-name>    
<param-value>EUC_JP</param-value>    
</init-param>    
</filter>   
<filter> 
<filter-name>Set Character Encoding</filter-name> 
<filter-class>filters.SetCharacterEncodingFilter</filter-class> 
<init-param> 
<param-name>encoding</param-name> 
<param-value>EUC_JP</param-value> 
</init-param> 
</filter> 
 過濾器的程式碼如下: 
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),它命名資源但不指定如何定位資源。
 
也就是說,我們通過 post 方法提交的引數實際上都是通過 uri 提交的,都由這個引數管理,如果沒有設定這個引數,則 tomcat 將使用預設的 iso8859-1 對客戶端的內容進行編碼!
 
useBodyEncodingForURI 使用與 Body 一樣的編碼來處理 URI, 這個設定是為了與 tomcat4保持相容。在 tomcat5 中,對post  的處理通過 前面的 URIEncoding 進行處理,對get 的內容依然通過 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,找到
<Connector acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" port="80" redirectPort="8443"> 
並在最後加上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",確保解碼格式與編碼格式統一;


方法四:
<mce:script type="text/javascript"><!--   
for(var i=0;i<document.links.length;i++){   
  
document.links[i].href=encodeURI(document.links[i].href);   
  
}   
// --></mce:script>  
<mce:script type="text/javascript"><!--
for(var i=0;i<document.links.length;i++){


document.links[i].href=encodeURI(document.links[i].href);


}
// --></mce:script>

 在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");

相關推薦

tomcat字符集中文亂碼解決

如果你搞Java web,相信你一定遇到過亂碼問題! 通常,你是否是這樣處理中文傳參的呢? 前臺: url=encodeURI(url);後臺:String name = new String(request.getParameter("name").getBytes("I

oracle服務端客戶端字符集不同導致中文亂碼解決方案

use 修改環境變量 描述 image nls_lang oracle服務 環境 分析 導致 1.問題描述 用pl/sql登錄時,會提示“數據庫字符集(ZHS16GBK)和客戶端字符集(2%)是不同的,字符集轉化可能會造成不可預期的後果”,具體問題是中文亂碼,如下圖 2.

tomcat 字符集設定 url中文亂碼解決大全

使用 tomcat 時,相信大家都回遇到中文亂碼的問題,具體表現為通過表單取得的中文資料為亂碼。 一、初級解決方法  通過一番檢索後,許多人採用瞭如下辦法,首先對取得字串按照 iso8859-1 進行解碼轉換,然後再按照 gb2312 進行編碼,最後得到正確的內容。示例

Tomcat中文亂碼解決辦法

-1 mage ima img con utf-8 結點 tor http 有時候發現自己將中文編碼後還是會存在亂碼的情況,解決辦法就是在Server.xml中的Connector結點,配置 URIEncoding="UTF-8"即可 Tomcat中文亂碼解決辦法

字符集中文亂碼如何解決

con linux 中文 conf 字節 如何解決 執行 什麽是 lang環境變量   什麽是字符集?簡單來說就是一套文字符號及其編碼。常用字符集有:   GBK 定長 雙字節 不是國際標準,支持的系統不少   UTF-8 非定長 1-4字節 廣泛支持,MYSQL也使

Linux下Tomcat向MySQL插入數據中文亂碼解決辦法

中文亂碼解決辦法Linux下Tomcat向MySQL插入數據中文亂碼解決辦法 一、問題 在windows上面使用eclipse開發的項目在windows上面運行一切正常,部署到騰訊雲時出現向MySQL數據庫中插入數據是中文亂碼 二、解決辦法 1、嘗試一直接在linux上面使用insert語句插入中文,正常2、

centos java tomcat 中文亂碼解決辦法

title 查詢 發現 即使 art 操作 https size tro 現象: cenos 部署java web 程序 ,java類中有中文 出現亂碼現象 即使使用: System.getProperty("中文") 控制臺都出現 ??????

IDEA開發Struts2和Tomcat中文亂碼解決方案

idea struts2中文亂碼。idea tomcat中文亂碼。 1.很可能是寫有中文的Java檔案編碼和前端不一樣導致。 統一為UTF-8編碼: jsp檔案 <%@ page contentType="text/html;charset=UTF-8" pag

Tomcat視窗標題,中文亂碼解決方法

   工作中,或多或少的原因,一臺伺服器中需要同時執行多個Tomcat服務(針對一臺伺服器如何同時執行多個Tomcat的配置,這裡不做論述,百度很多),為了便於區分各個Tomcat的功能,通常會選擇修改

Tomcat 中 jsp 中文亂碼顯示處理解決方案

JSP 中文亂碼處理解決方案初學JSP,尤其是Tomcat環境,經常會因為中文漢字字符集設定問題導致中文亂碼,本文就這一問題提出解決方案,解決中文亂碼問題,供各位參考,我採用的方案是統一字符集至UTF-

MyEclipse和tomcat對於jsp中文亂碼解決方法

一、Java和jsp 中文亂碼原因和解決方法: Java的核心和class檔案是基於unicode的,這使Java程式具有良好的跨平臺性,但也帶來了一些中文亂碼問題的麻煩。原因有兩方面: 第一方面:Java和JSP檔案本身編譯時產生的亂碼問題: Java(包括JSP

JAVA中文亂碼解決辦法/修改TOMCAT預設編碼

頁面為UTF-8,jquery的ajax方法為utf-8傳值,中文會出現亂碼,給java頁面傳值時需要進行兩次轉碼encodeURI(); 例如: $.post("page.do",{str:encodeURI(encodeURI("中文"))},function(data){alert(data)

資料庫中文亂碼解決方案總結,tomcat+mysql+hibernate

我的開發環境是eclipse+tomcat+mysql+hibernate,資料落地時發現中文都成了?,網上一搜,原因有很多,這邊總結下,大家碰到可以按著一一排查: 一般編碼都會常用UTF-8編碼 1. 資料庫編碼 檢視mysql資料的的編碼,確實是utf-8 如

linux 下,解決tomcat伺服器接收中文亂碼的問題

最近在整理以前的專案。刪了很多收集的東西。這個還不錯,貼出來和大家分享下。 在tomcat下的conf目錄資料夾下server.xml檔案中新增 useBodyEncodingForURI="true" 能很好的解決此類問題的發生。 可以在server.xml檔案中搜

Tomcat中 日誌(控制檯)中文亂碼解決方法

背景: windows系統以Linux指令碼啟動服務 問題 在Tomcat中有時輸出的日誌中文為亂碼,包括控制檯視窗和輸出日誌檔案中都為亂碼。 解決方案 JDK引用的設定 Java引用引數新增"-Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8" 將上面

SecureCRT中文亂碼解決方法--字符集設定(Linux環境)

本文參考了一下文章,僅供學習。 http://www.2cto.com/os/201504/388810.html 1、首先進入SecureCRT工具 ‘Option’->‘Session Options’-> 'Terminal'->'Emulation

tomcat配置及中文亂碼問題的解決方案

本文要解決的問題: 掌握tomcat的配置,同時解決使用過程中一系列的亂碼問題。 tomcat中文亂碼問題 一、Java中文問題的由來   Java的核心和class檔案是基於unicode的

tomcat伺服器,url get請求中文亂碼解決方案

解決方法,在tomcat conf/server.xml 中新增 紅色部分,然後重啟服務即可。     <Connector port="8080" protocol="HTTP/1.1" 

解決Tomcat 5 下中文亂碼問題

使用 tomcat 時,相信大家都回遇到中文亂碼的問題,具體表現為通過表單取得的中文資料為亂碼。下面是本人解決之路。一、初級解決方法通過一番檢索後,許多人採用瞭如下辦法,首先對取得字串按照 iso8859-1 進行解碼轉換,然後再按照 gb2312 進行編碼,最後得到正確

【Oracle筆記】Oracle因安裝時未設定字符集導致中文亂碼解決方案

在Centos6.5上安裝Oracle11g沒有設定字符集,採用的是作業系統預設字符集:WE8MSWIN1252,將字符集修改為:ZHS16GBK。 [[email protected] ~]$ sqlplus / as sysdba SQL*Plus: Rel