1、jsp教程與頁面參數之間的亂碼
jsp擷取頁面參數時一般採用系統預設的編碼方式,如果頁面參數的編碼類別型和系統預設的編碼類別型不一致,很可能就會出現亂碼。解決這類亂碼問題的基本方法是在頁面擷取參數之前,強制指定request擷取參數的編碼方式:request.setcharacterencoding("gbk")或request.setcharacterencoding("gb2312")。
如果在jsp將變數輸出到頁面時出現了亂碼,可以通過設定response.setcontenttype("text/html;charset=gbk")或response.setcontenttype("text/html;charset=gb2312")解決。
如果不想在每個檔案裡都寫這樣兩句話,更簡潔的辦法是使用servlet規範中的過慮器指定編碼,過濾器的在web.xml中的典型配置和主要代碼如下:
web.xml:
<filter>
<filter-name>characterencodingfilter</filter-name>
<filter-class>net.vschool.web.characterencodingfilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>gbk</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterencodingfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
characterencodingfilter.java:
public class characterencodingfilter implements filter
{
protected string encoding = null;
public void init(filterconfig filterconfig) throws servletexception
{
this.encoding = filterconfig.getinitparameter("encoding");
}
public void dofilter(servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception
{
request.setcharacterencoding(encoding);
response.setcontenttype("text/html;charset="+encoding);
chain.dofilter(request, response);
}
}
2、java與資料庫教程之間的亂碼
大部分資料庫都支援以unicode編碼方式,所以解決java與資料庫之間的亂碼問題比較明智的方式是直接使用unicode編碼與資料庫互動。很多資料庫驅動自動支援unicode,如microsoft的sqlserver驅動。其他大部分資料庫驅動,可以在驅動的url參數中指定,如如mm的mysql教程驅動:
jdbc:mysql://localhost/webcldb?useunicode=true&characterencoding=gbk。
3、java與檔案/流之間的亂碼
java讀寫檔案最常用的類是fileinputstream/fileoutputstream和filereader/filewriter。其中fileinputstream和fileoutputstream是基於位元組流的,常用於讀寫二進位檔案。讀寫字元檔案建議使用基於字元的filereader和filewriter,省去了位元組與字元之間的轉換。但這兩個類的建構函式預設使用系統的編碼方式,如果檔案內容與系統編碼方式不一致,可能會出現亂碼。在這種情況下,建議使用filereader和filewriter的父類:inputstreamreader/outputstreamwriter,它們也是基於字元的,但在建構函式中可以指定編碼類別型:
inputstreamreader(inputstream in, charset cs) 和outputstreamwriter(outputstream out, charset cs)。
4、其他
上面提到的方法應該能解決大部分亂碼問題,如果在其他地方還出現亂碼,可能需要手動修改代碼。解決java亂碼問題的關鍵在於在位元組與字元的轉換過程中,你必須知道原來位元組或轉換後的位元組的編碼方式,轉換時採用的編碼必須與這個編碼方式保持一致。我們以前使用resin伺服器,使用smartupload組件上傳檔案,上傳檔案同時傳遞的中文參數擷取沒有亂碼問題。當在linux中把resin設定成服務後,上傳檔案同時的中文參數擷取出現了亂碼。這個問題困擾了我們很久,後來我們分析smartupload組件的源檔案,因為檔案上傳採用的是位元組流的方式,裡麵包含的參數名稱和值也是位元組流的方式傳遞的。smartupload組件讀取位元組流後再將參數名稱和值從位元組流中解析出來,問題就出現在smartupload將位元組流轉換成字串時採用了系統預設的編碼,而將resin設定成服務後,系統預設的編碼可能發生了改變,因此出現了亂碼。後來,我們更改了smartupload的源檔案,增加了一個屬性charset和setcharset(string)方法,將upload()方法中提取參數語句:
string value = new string(m_binarray, m_startdata, (m_enddata - m_startdata) + 1 );
改成了
string value = new string(m_binarray, m_startdata, (m_enddata - m_startdata) + 1, charset );
終於解決了這個亂碼問題。