jsp亂碼問題的解決
2009-07-15 10:32
1.JSP頁面亂碼這種亂碼的原因是應為沒有在頁面裡指定使用的字符集編碼,解決方法:只要在頁面開始地方用下面代碼指定字符集編碼即可,<%@ page contentType="text /html; charset=gb2312"? %>
2.資料庫亂碼這種亂碼會使你插入資料庫的中文變成亂碼,或是讀出顯示時也是亂碼,解決方法如下:
在資料庫連線字串中加入編碼字元集(資料來源連線同樣適用)
String Url="jdbc:mysql://localhost/digitgulf?
user=root&password=root&useUnicode=true&characterEncoding=GB2312";
並在頁面中使用以下程式碼:
response.setContentType("text/html;charset=gb2312");
request.setCharacterEncoding("gb2312");
3.中文作為參數傳遞亂碼當我們把一段中文字元當作參數傳遞個另一頁時,也會出現亂碼狀況,解決方法如下:
參數傳遞時對參數編碼,例如RearshRes.jsp?keywords=" + java.net.URLEncoder.encode(keywords)
然後在接收參數頁面使用如下語句接收keywords=new String(request.getParameter("keywords").getBytes("8859_1"));
亂碼的核心問題還是字元集編碼問題,只要掌握了這一點,一般的亂碼問題都可以解決。
------------------------------------------
自從接觸Java和JSP以來,就不斷與Java的中文亂碼問題打交道,現在終於得到了徹底的解決,現將我們的解決心得與大家共享。
一、Java中文問題的由來
Java的核心和class檔案是基於unicode的,這使得Java程式具有良好的跨平台性,但也帶來了一些中文亂碼問題的麻煩。原因主要有兩方面,Java和JSP檔案本身編譯時產生的亂碼問題和Java程式於其他媒介互動產生的亂碼問題。
首先Java(包括JSP)原始檔中很可能包含有中文,而Java和JSP原始檔的保存方式是基於位元組流的,如果Java和JSP編譯成class檔案過程中,使用的編碼方式與原始檔的編碼不一致,就會出現亂碼。基於這種亂碼,建議在Java檔案中盡量不要寫中文(註解部分不參與編譯,寫中文沒關係),如果必須寫的話,盡量手動帶參數-ecoding GBK或-ecoding gb2312編譯;對於JSP,在檔案頭加上<%@ page contentType="text/html;charset=GBK"%>或<%@ page contentType="text/html;charset=gb2312"%>基本上就能解決這類亂碼問題。
本文要重點討論的是第二類亂碼,也就是Java程式與其他儲存媒介互動時所產生的亂碼。許多儲存媒介,如資料庫,文件,流等的儲存方式都是基於位元組流的,Java程式與這些媒介互動時就會發生字元(char)與位元組(byte)之間的轉換,例如從頁面提交表單中提交的資料在Java程式裡顯示亂碼等情況。
如果在以上轉換過程中所使用的編碼方式與位元組原有的編碼不一致,很可能就會出現亂碼。
二、解決方法
對於流行的Tomcat來說,有以下兩種解決方法:
1) 更改D:Tomcatconfserver.xml,指定瀏覽器的編碼格式為「簡體中文」:
方法是找到server.xml 中的
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" URIEncoding='GBK' />
標記,粗體字是我添加的。
可以這樣驗證你的更改是否成功:在更改之前,在你出現亂碼的頁面的IE瀏覽器,點擊菜單“查看|編碼”,會發現“西歐(ISO)”處於選中狀態。而更改後,點選選單“查看|編碼”,會發現“簡體中文(GB2312)”處於選取狀態。
b)更該Java 程序,我的程式是這樣的:
public class ThreeParams extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=GBK");
…
}
}
粗體字是必需要的,它的作用是讓瀏覽器把Unicode字元轉換成GBK字元。這樣頁面的內容和瀏覽器的顯示模式都設為GBK,就不會亂碼了。
tomcat下中文的徹底解決
這年頭開發一個項目,伺服器是tomcat,作業系統是xp,採用的是MVC架構,模式是採用Facade模式,總是出現亂碼,自己也解決了很多天,同事也幫忙解決,也參考了網路上眾多網友的文章和意見,總算搞定。但是好記性不如爛筆桿,所以特意記下,以防止自己遺忘,同時也給那些遇到同樣問題的人提供一個好的參考途徑:
(一) JSP頁面上是中文,但看的是後是亂碼:
解決的方法就是在JSP頁面的編碼的地方<%@ page language="java" contentType="text/html;charset=GBK" %>,因為Jsp轉成Java檔案時的編碼問題,預設的話有的伺服器是ISO-8859-1,如果一個JSP中直接輸入了中文,Jsp把它當作ISO8859-1來處理是肯定有問題的,這一點,我們可以透過查看Jasper所產生的Java中間文件來確認
(二) 當用Request物件取得客戶提交的漢字代碼的時候,會出現亂碼:
解決的方法是:要設定一個filter,也就是一個Servelet的過濾器,程式碼如下:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class CharacterEncodingFilter implements Filter {
private FilterConfig config;
private String encoding = "ISO8859_1";
public void destroy() {
System.out.println(config);
config = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
//chain.doFilter(request, response);
chain.doFilter(request, response);
}
public void init(FilterConfig config) throws ServletException {
this.config = config;
String s = config.getInitParameter("encoding");
if (s != null) {
encoding = s;
}
}
}
}
配置web.xml
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.SetCharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果你的還是出現這種情況的話你就往下看看是不是你出現了第四中情況,你的Form提交的數據是不是用get提交的,一般來說用post提交的話是沒有問題的,如果是的話,你就看看第四解決的辦法。
還有就是對含有漢字字元的資訊進行處理,處理的程式碼是:
package dbJavaBean;
public class CodingConvert
{
public CodingConvert()
{
//
}
public String toGb(String uniStr){
String gbStr = "";
if(uniStr == null){
uniStr = "";
}
try{
byte[] tempByte = uniStr.getBytes("ISO8859_1");
gbStr = new String(tempByte,"GB2312");
}
catch(Exception ex){
}
return gbStr;
}
public String toUni(String gbStr){
String uniStr = "";
if(gbStr == null){
gbStr = "";
}
try{
byte[] tempByte = gbStr.getBytes("GB2312");
uniStr = new String(tempByte,"ISO8859_1");
}catch(Exception ex){
}
return uniStr;
}
}
你也可以在直接的轉換,首先你將獲取的字串用ISO-8859-1進行編碼,然後將這個編碼存放到一個位元組數組中,然後將這個數組轉換成字串物件就可以了,例如:
String str=request.getParameter(“girl”);
Byte B[]=str.getBytes(“ISO-8859-1”);
Str=new String(B);
透過上述轉換的話,提交的任何資訊都能正確的顯示。
(三) 在Formget請求在服務端用request. getParameter(“name”)時回傳的是亂碼;按tomcat的做法設定Filter也沒有用或用request.setCharacterEncoding("GBK");也不管用問題是出在處理參數傳遞的方法上:如果在servlet中用doGet(HttpServletRequest request, HttpServletResponse response)方法進行處理的話前面即使是寫了:
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");
也是不起作用的,返回的中文還是亂碼! ! !如果把這個函式改成doPost(HttpServletRequest request, HttpServletResponse response)一切就OK了。
同樣,在用兩個JSP頁面處理表單輸入之所以能顯示中文是因為用的是post方法傳遞的,改成get方法依舊不行。
由此可見在servlet中用doGet()方法或是在JSP中用get方法進行處理要注意。這畢竟涉及到要透過瀏覽器傳遞參數訊息,很有可能引起常用字元集的衝突或是不匹配。
解決的辦法是:
1) 開啟tomcat的server.xml文件,找到區塊,加入下列一行:
URIEncoding=”GBK”
完整的應如下:
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" acceptCount="100" debug="0" connectionTimeout="20000」 true" URIEncoding="GBK"/>
2)重啟tomcat,一切OK。
需要加入的原因大家可以去研究$TOMCAT_HOME/webapps/tomcat-docs/config/http.html下的這個檔案就可以知道原因了。要注意的是:這個地方如果你要是用UTF-8的時候在傳遞的過程中在Tomcat中也是要出現亂碼的情況,如果不行的話就換別的字符集。
(四) JSP頁面上有中文,按鈕上面也有中文,但是透過伺服器查看頁面的時候出現亂碼:
解決的方法是:首先在JSP檔案中不應該直接包含本地化的訊息文本,而是應該透過<bean:message>標籤從Resource Bundle中取得文字。應該把你的中文文字放到Application.properties檔案中,這個檔案放在WEB-INF/classes/*下,例如我在頁面裡有姓名,年齡兩個label,我首先就是要建一個Application.properties,裡面的內容應該是name=”姓名” age=”年齡”,然後我把這個文件放到WEB-INF/classes/properties/下,接下來根據Application.properties文件,對他進行編碼轉化,創建一個中文資源文件,假定名字是Application_cn.properties。在JDK中提供了native2ascii指令,他能夠實現字元編碼的轉換。在DOS環境中找到你放置Application.properties的這個檔案的目錄,在DOS環境中執行指令,將產生按GBK編碼的中文資源檔案Application_cn.properties:native2ascii ?encoding gbk Application.properties Application_cn.properties執行上述指令以後將產生以下內容的Application_cn.properties檔案:name=u59d3u540d age=u5e74u9f84,在Struts-config.xml中設定:<message-resources parameter="properties.Application_cn"/>。到這一步,基本上完成了一大半,接著你就要在JSP頁面上寫<%@ page language="java" contentType="text/html;charset=GBK" %>,到名字的那個label是要寫<bean:message key=”name”>,這樣的化在頁面上出現的時候就會出現中文的姓名,年齡這個也是一樣,按鈕上漢字的處理也是同樣的。
(五) 寫入資料庫是亂碼:
解決的方法:要設定一個filter,也就是一個Servelet的過濾器,程式碼就像第二種時候一樣。
如果你是透過JDBC直接連結資料庫的時候,設定的程式碼如下:jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&characterEncoding=GBK,這樣保證到資料庫中的程式碼是不是亂碼。
如果你是透過資料來源連結上面同樣適合如果你是配置正確的化,當你輸入中文的時候到資料庫中就是中文了,有一點要注意的是你在顯示資料的頁面也是要用<%@ page language="java" contentType="text/html;charset=GBK" %>這行程式碼的。要注意的是有的前台的人員在寫程式碼的是後用Dreamver寫的,寫了一個Form的時候把他改成了一個jsp,這樣有一個地方要注意了,那就是在Dreamver中Action的提交方式是request的,你需要把他該過來,因為在jsp的提交的過程中緊緊就是POST和GET兩種方式,但是這兩種方式提交的代碼在編碼方面還是有很大不同的,這個在後面的地方進行說明
文章摘要:
此處主要講述關於jsp亂碼問題的解決
1、 最基本的亂碼問題。
PHPCE.CN,設計手冊
3.表單get提交方式的亂碼處理方式。
如果使用get方式提交中文,接受參數的頁面也會出現亂碼,這個亂碼的原因也是tomcat的內部編碼格式iso8859-1導致。 Tomcat會以get的預設編碼方式iso8859-1對漢字編碼,編碼後追加到url,導致接受頁面得到的參數為亂碼/、。
解決辦法:
A、使用上例中的第一種方式,將接受到的字元解碼,再轉碼。
B、Get走的是url提交,而在進入url之前已經進行了iso8859-1的編碼處理。想要影響這個編碼就需要在server.xml的Connector節點增加useBodyEncodingForURI="true"
屬性配置,即可控制tomcat對get方式的漢字編碼方式,上面這個屬性控制get提交也是用request.setCharacterEncoding("UTF-8")所設定的編碼格式進行編碼。所以自動編碼為utf-8,接受頁面正常接受就可以了。但我認為真正的編碼過程是,tomcat又要根據更改D:Tomcatconfserver.xml,指定瀏覽器的編碼格式為「簡體中文」:
<Connector port="8080"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
debug="0" connectionTimeout="20000" useBodyEncodingForURI="true"
disableUploadTimeout="true" URIEncoding=”UTF-8”/> PHPCE.CN,設計手冊裡面所設定的URIEncoding=”UTF-8”再進行一次編碼,但由於已經編碼為utf-8,再編碼也不會有變化了。如果是從url取得編碼,接受頁面則是根據URIEncoding=”UTF-8”來進行解碼的。
需要加入的原因大家可以去研究$TOMCAT_HOME/webapps/tomcat-docs/config/http.html下的這個文件就可以知道原因了可以這樣驗證你的更改是否成功:在更改前,在你出現亂碼的頁面的IE瀏覽器,點選選單“查看|編碼”,會發現“西歐(ISO)”處於選取狀態。而更改後,點選選單“查看|編碼”,會發現“簡體中文(GB2312)”處於選取狀態。
4.上傳檔案時的亂碼解決上傳檔案時,form表單設定的都是enctype="multipart/form-data"。這種方式以流方式提交文件。如果使用apach的上傳元件,會發現有很多亂碼想像。這是因為apach的先期commons-fileupload.jar有bug,取出漢字後進行解碼,因為這種方式提交,編碼又自動使用的是tomcat缺省編碼格式iso-8859-1。但出現的亂碼問題是: 句號,逗號,等特殊符號變成了亂碼,漢字如果數量為奇數,則會出現亂碼,偶數則解析正常。
解決方式: 下載commons-fileupload-1.1.1.jar 這個版本的jar已經解決了這些bug。
但是取出內容時仍需要對取出的字元進行從iso8859-1到utf-8轉碼。已經能得到正常所有漢字以及字符。
5.Java程式碼關於url請求,接受參數的亂碼
url的編碼格式,取決於上面所說的URIEncoding=”UTF-8”。 如果設定了這個編碼格式,則表示所有到url的漢字參數,都必須進行編碼才可以。否則得到的漢字參數值都是亂碼,例如一個連結Response.sendDerect(“/a.jsp?name=張大維”);而在a.jsp裡面直接使用
PHPCE.CN,設計手冊
String name = request.getParameter("name");得到的就是亂碼。因為規定了必須是utf-8才可以,所以,這個轉向應該這樣寫:
Response.sendDerect(“/a.jsp?name=URLEncode.encode(“張大維”,”utf-8”);才可以。
如果不設定這個參數URIEncoding=”UTF-8”, 會怎麼樣呢? 不設定則就使用了缺省的編碼格式iso8859-1。問題又出來了,第一就是參數值的個數如果是奇數個數,則就可以正常解析,如果使偶數個數,得到最後字元就是亂碼。還有就是如果最後一個字元如果是英文,就能正常解析,但中文的標點符號仍出現亂碼。權宜之計,如果您的參數中沒有中文標點符號,則可以在參數值最後加上一個英文符號來解決亂碼問題,得到參數後再去掉這個最後面的符號。也可以湊或使用。
6. 腳本程式碼關於url請求,接受到的參數亂碼腳本中也會進行頁面轉向的控制,也會涉及到附帶參數,並在接受頁面解析這個參數的情況。如果這個漢字參數不進行URIEncoding=”UTF-8”所指定的編碼處理,則接受頁面接受到的漢字也是亂碼。腳本處理編碼比較麻煩,必須有相應的編碼腳本對應文件,然後調用腳本中的方法對漢字進行編碼即可。
7. 關於jsp在MyEclipse中開啟的亂碼問題對於一個已經存在的項目,Jsp檔案的儲存格式可能是utf-8。如果新安裝的eclipse,則預設開啟使用的編碼格式都是iso8859-1。所以導致jsp裡面的漢字出現亂碼。這個亂碼比較容易解決,直接到eclipse3.1的偏好設定裡面找到general-〉edidor,設定為您的檔案開啟編碼為utf-8即可。 Eclipse會自動重新以新的編碼格式開啟。漢字即可正常顯示。
8. 關於html頁面在eclipse中打開出現亂碼情況由於大部分頁面都是由dreamweaver製作,其存儲格式跟eclipse的識別有差別導致。
一般這種情況,在eclipse中新建一個jsp,直接從dreamweaver複製頁面內容貼上到jsp即可。
PHPCE.CN,設計手冊
這個亂碼問題是最簡單的亂碼問題。一般新會出現。就是頁面編碼不一致導致的亂碼。
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page contentType="text/html;charset=iso8859-1"%>
<html>
<head>
<title>中文問題</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
</head>
<body>
我是個好人
</body>
</html>
三個地方的編碼。
第一個地方的編碼格式為jsp檔案的儲存格式。 Ecljpse會根據這個編碼格式儲存檔案。並編譯jsp文件,包括裡面的漢字。
第二處編碼為解碼格式。因為存為UTF-8的檔案被解碼為iso8859-1,這樣如有中文肯定出亂碼。也就是必須一致。而第二處所在的這一行,可以沒有。缺省也是使用iso8859-1的編碼格式。所以如果沒有這一行的話,「我是個好人」也會出現亂碼。必須一致才可以。
第三處編碼為控制瀏覽器的解碼方式。如果前面的解碼都一致且無誤的話,這個編碼格式沒有關係。有的網頁出現亂碼,就是因為瀏覽器無法確定要使用哪種編碼格式。因為頁面有時候會嵌入頁面,導致瀏覽器混淆了編碼格式。出現了亂碼。 PHPCE.CN,設計手冊
2.表單使用Post方式提交後接收到的亂碼問題這個問題也是常見的問題。這個亂碼也是tomcat的內部編碼格式iso8859-1在搗亂,也就是說post提交時,如果沒有設定提交的編碼格式,則會以iso8859-1方式進行提交,接受的jsp卻以utf-8的方式接受。導致亂碼。既然這樣的原因,以下有幾種解決方式,並進行比較。
A、接受參數時進行編碼轉換
String str = new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8") ; 這樣的話,每一個參數都必須這樣進行轉碼。很麻煩。但確實可以拿到漢字。
B、在請求頁面上開始處,執行請求的編碼代碼, request.setCharacterEncoding("UTF-8"),把提交內容的字元集設為UTF-8。這樣的話,接受此參數的頁面就不必在轉碼了。直接使用
String str = request.getParameter("something");即可得到漢字參數。但每頁都需要執行這句話。這個方法也對post提交的有效果,對於get提交和上傳檔案時的enctype="multipart/form-data"是無效的。稍後下面單獨對這個兩個的亂碼情況再進行說明。
C、為了避免每頁都要寫request.setCharacterEncoding("UTF-8"),建議使用過濾器對所有jsp
進行編碼處理。這個網上有很多例子。請大家自己查