談談WEB開發中的苦大難字元集問題

來源:互聯網
上載者:User

標籤:http   io   color   ar   os   使用   java   sp   for   

http://www.lanceyan.com/tech/arch/web_luanma.html記得剛做javaweb開發的時候被這個編碼問題搞得暈頭轉向,經常稀裡糊塗的編碼正常了一會編碼又亂了。那個時候迫於項目進度大多都是知其然不知其所以然。後來有時間就把整個體系搞了個遍,終於摸通了來龍去脈。

在C++的CGI開發時大家喜歡用latin,這個屬於位元組方式的編碼格式,儲存mysql節約空間,而C++也是比較容易控制到byte層級的語言。所以經過架構封裝基本也問題不大。

在Java語言中,要涉及修改編碼問題的地方還真多。一個地方沒有設好就會亂碼滿天飛。大概總結包括以下這幾部分:瀏覽器、伺服器、資料庫、作業系統。

瀏覽器:
如果使用範本語言,html需要設定顯示的字元集。這個適用於瀏覽器判斷什麼編碼顯示。

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

擴充,瀏覽器識別編碼的順序:
1.如果HTTP頭部申明了charset,則會使用HTTP頭部的,
2.讓HTTP頭部沒有設定,則會去解析meta標籤的,
3.如果meta也沒有的話,瀏覽器會根據是否設定了auto detect來進行編碼識別,
4.否則會使用本地UI的字元編碼。

伺服器:
對於JSP等動態語言,需要在jsp頭部設定編碼格式,J2EE伺服器解析這個JSP的時候才會把整個頁面編碼為UTF-8輸出,不然就按照系統預設編碼格式ISO-8859-1輸出了。JSP設定格式如下:

<%@ page language= "java" contentType = "text/html; charset=UTF-8"
      pageEncoding ="UTF-8" %>

大家都知道,JSP對應的就是servlet。servlet的編碼對應如下設定:

public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException{
response.setContentType("text/html;charset=utf-8");
}

還有不要漏掉大家常用的spring工具類,編碼轉換filter,很實用。在你用struts、spring mvc時這個過濾器幫你轉換沒有設定的編碼過濾。如下設定:

       <filter>
             <filter-name> Set Character Encoding</filter-name>
             <filter-class>
                  org.springframework.web.filter.CharacterEncodingFilter
             </filter-class>
             <init-param>
                   <param-name> encoding</param-name>
                   <param-value> UTF-8</param-value>
             </init-param>
       </filter>

萬一還有亂碼怎麼辦呢?doGet方式的參數傳遞肯定會有亂碼問題。只需要在tomcat的監聽器裡設定編碼字元集如下(檔案一般儲存在 /tomcat安裝目錄/conf/server.xml ):

<Connector port="80" protocol="HTTP/1.1" 
              connectionTimeout="20000" 
              redirectPort="8443" URIEncoding="utf-8"   />

大家在開發的時候別忘了java檔案本身也是有編碼格式的。在類檔案右鍵查看屬性。

 

 

如果開發時忘記變更檔的編碼格式,windows預設是GBK的,後來又要一直到utf8編碼的linux怎麼辦。檔案巨多,總不能一個一個去更改吧。其實很簡單,只需要在java命令的環境參數設定 -Dfile.encoding=GBK 解決。

編譯java代碼時,如果使用ant需要在javac裡設定編譯的字元集。這樣列印的log輸出到檔案或者控制台上就不會亂碼了。

<javac debuglevel= "source,lines" source= "1.6"   encoding= "utf-8">

maven編譯時間設定的字元集:

 < artifactId> maven-compiler-plugin </artifactId >
       < version> 2.5 </version >
                        
         < configuration>
           < optimize> true </optimize >
           < showDeprecation> false </showDeprecation >
           < debuglevel> lines,source </debuglevel >
            < source> 1.6 </source >
            < target> 1.6 </target >
            < encoding> UTF-8 </encoding >
            < meminitial> 128m </meminitial >  
             < maxmem> 768m </maxmem >
                        
         </ configuration>

sqlmap的sql xml,sping的xml 也是需要設定的,因為涉及到跨平台。 頂上添加:

<!--?xml version="1.0" encoding="UTF-8"?-->

資料庫:
這裡列出大家用的最多的Mysql字元集設定。開啟mysql的設定檔( linux 一般在 /etc/my.cnf ,windows在mysql的安裝目錄 my.ini)。設定如下:

[mysqld]
default-character-set = utf8

[ mysql]
character_set_server = utf8

jdbc需要設定
jdbc : mysql://192.168.0.237:3306/dzh_db?useUnicode=true&characterEncoding=UTF-8

這些都設定了一般的中文是不會有問題的。

不過最近出現了一個問題很搞怪。以前以為所有的字元只要設定好了所有資料都可以錄入資料庫,結果有些字元就不行,比如●■★這類型的。後來把這些字元變成位元組碼,居然不是三位utf8的,我擦,大汗淋漓。後來查詢可以通過過濾utf8 特殊字元的方式處理。

public static String Utf2String (byte buf[]) {
int len = buf.length ;
StringBuffer sb = new StringBuffer(len / 2);
for (int i = 0; i &lt; len; i++) {

if (by2int(buf[i]) &lt;= 0x7F)
sb.append(( char ) buf[i]);
else if (by2int(buf[i]) &lt;= 0xDF &amp;&amp; by2int(buf[i]) &gt;= 0xC0) {
int bh = by2int(buf[i] &amp; 0x1F);
int bl = by2int(buf[++i] &amp; 0x3F);

bl = by2int(bh &lt;&lt; 6 | bl); bh = by2int(bh &gt;&gt; 2);
int c = bh &lt;&lt; 8 | bl;
sb.append(( char ) c);
} else if (by2int(buf[i]) &lt;= 0xEF &amp;&amp; by2int(buf[i]) &gt;= 0xE0) {
int bh = by2int(buf[i] &amp; 0x0F);
int bl = by2int(buf[++i] &amp; 0x3F);
int bll = by2int(buf[++i] &amp; 0x3F);

bh = by2int(bh &lt;&lt; 4 | bl &gt;&gt; 2);
bl = by2int(bl &lt;&lt; 6 | bll);

int c = bh &lt;&lt; 8 | bl;
// 空格轉換為半形
if (c == 58865) {
c = 32;
}
sb.append(( char ) c);

}
}
return sb.toString();
}

或者把mysql的字元集改為 utf8mb4 ,記得這個只有mysql55支援哦!

[mysqld]
default-character-set =utf8mb4

[ mysql]
character_set_server = utf8mb4

作業系統:
windows預設是gbk,一般不需要變動。不過大家又想每個檔案都要建立為utf8格式怎麼辦,不可能我們每個檔案建立後都去用屬性改變一下?太麻煩!直接在eclipse設定後,同種類型的檔案建立都會是utf8格式。

 

linux,可以有兩個地方修改基本就足夠了:
vi /etc/sysconfig/i18n
修改

LANG="zh_CN.GB3212"
LANGUAGE="zh_CN.GB18030:zh_CN.GB2312:zh_CN"
SUPPORTED="zh_CN.GB18030:zh_CN:zh:en_US.UTF-8:en_US:en"

vi /etc/profile

export LC_ALL="zh_CN.GB2312"
export LANG="zh_CN.GB2312"

原創文章,轉載請註明: 轉載自LANCEYAN.COM

談談WEB開發中的苦大難字元集問題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.