流光溢彩

          修天爵而人爵隨之
          posts - 8, comments - 3, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          ?????? Tomcat 下最容易到的問題就是中文亂碼問題了 , 下面就來談談我在 Windows +Tomcat5 下調試 JSP 程序時 , 所碰到的問題以及解決辦法。

          ?????? 這次調試所遇到的亂碼問題主要有三類:

          一、 頁面字符亂碼。

          即整個頁面出現漢字亂碼(不管是用 HTML 格式寫的,還是用 print() 方法輸出的漢字,全部顯示為亂碼)。

          二、 Request 傳遞亂碼。

          在用 post get 等方法,傳遞變量時出現亂碼;需要進行 cookies 或者 session 調用時出現亂碼。

          三、 數據庫存取亂碼。

          在進行數據庫存取時,或者存入數據庫,或者讀出數據時出再亂碼。

          ?

          ?????? 下面就這三類亂碼進行分析并談談我的解決方法:

          一、 頁面字符亂碼。

          ?

          ????????????? 我們先寫下這樣的一個 jsp 文件:

          ????????????? //testPagErr.jsp

          ????????????? <%

          ???????????????????? out.println(“ 能顯示中文嗎? ”);

          %>

          如果我們直接按照默認的配置啟動 Tomcat5 ,然后訪問這一個頁面的時,將輸出的中文將顯示為亂碼。其原因很簡單,這是由于在 Tomcat5 默認的設置下,將按照 ISO-8859-1 進行編碼。解決這個問題最直接的做法是,有每個有中文輸出的 jsp 文件的開頭加一句:

          <%@ ?page contentType="text/html;charset=GBK" // (改成 GB2312 亦可,本文中均以 GBK 為例) %>

          ?????? 但是這樣做存在很多問題,首先,這一句開指令在 include 的時候,不能夠被子文件繼承,因此,我們必須在子文件中重新加入這一句話,但如果大小寫不話,就會出現類似于以下的錯誤:

          org.apache.jasper.JasperException: /top.jsp(1,1) Page directive: illegal to have multiple occurrences of contentType with different values (old: text/html;charset=gbk, new: text/html;charset=GBK).

          ?????? 那么 , 這樣子定義就有點恐怖了,假如有一個要作 Head.jsp 的頭文件,我們試著在其中加入 <%@ page contentType="text/html;charset=GBK" %> 要在眾多的文件中被包含,而這些文件是由不同的程序只寫的,有的習慣用“ gbk , 有的用“ GBK ”,還有喜歡用“ GB2312,那怎么辦啊?難到要一個文件一個文件地去改過來?就算你可以用一些編輯器 Replace in Files 功能把所有的文件更正過來,但這樣做必然會影響系統的可移植性。

          同樣 , 如果 "text/html;charset=GBK" 的間隔不一致的話,也會出錯,而且,一旦程被修改成這樣的模式,你的程序就不能在舊的 jsp/servlet container 上執行了,因為舊的規格是不允許在 include 文檔中再次中現 <%@ page ... %> 這樣的定義的。

          因此上,如果采用上述方法的話,在一兩個頁面上也可行,但此法僅為權 益之計。

          J2EE1.4 中,關于 jsp 的部分里有一個 <jsp-config> XML Tag ,這個區塊是用來定義 jsp 的相關特殊屬性的,它包含所采用的 taglib 和下面我們要用到的 <jsp-property-group> ,定義字符編碼的方法就定義在 <jsp-property-group> 之中,找到你正在開發的 webapps 目錄(一般在 $TOMCAT_HOME\webapps\your_web_site\ )下的 WEB-INF ,打開 web.xml( 如果沒的話,就創建一個 ) ,作如下修改:

          ?

          <?xml version="1.0" encoding="ISO-8859-1"?>

          ?

          <!— 這一段是 xml   head 的定義,特別注意,最后的 version="2.4" Tomcat 5會去檢測這個版本的信息,只有 2.4 的才會去處理 jsp-config 中的參數 -->

          <web-app xmlns="http://java.sun.com/xml/ns/j2ee"

          ??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          ??? xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"

          version="2.4">

          <!— ------------------------------------------------------------------------------------------ -->

          ?

          <!— 這一部分就是我們新加入的,起作用的區塊 -->

          <jsp-config>

          ?????? <jsp-property-group>

          ?????? ??? <description>

          ????????????? Special property group for JSP Configuration JSP example.

          ?????? ??? </description>

          ?????? ??? <display-name>JSPConfiguration</display-name>

          ?????? ??? <url-pattern>*.jsp</url-pattern>

          ?????? ??? <el-ignored>true</el-ignored>

          ?????? ??? <page-encoding>GBK</page-encoding>

          ?????? ??? <scripting-invalid>flase</scripting-invalid>

          ?????? ??? <include-prelude></include-prelude>

          ?????? ??? <include-coda></include-coda>

          ?

          ?????? ??? <description>

          ????????????? Special property group for JSP Configuration JSP example.

          ?????? ??? </description>

          ?????? ??? <display-name>JSPConfiguration</display-name>

          ?????? ??? <url-pattern>*.html</url-pattern>

          ?????? ??? <el-ignored>true</el-ignored>

          ?????? ??? <page-encoding>GBK</page-encoding>

          ?????? ??? <scripting-invalid>flase</scripting-invalid>

          ?????? ??? <include-prelude></include-prelude>

          ?????? ??? <include-coda></include-coda>

          ?????? </jsp-property-group>

          </jsp-config>

          <!— ------------------------------------------------------------------------------------------ -->

          </web-app>

          另外,如果 Tomcat5 Apache 整和,最好把 httpd.conf 中的 AddDefaultCharset 的值設為 GBK.

          二、 equest 傳遞亂碼

          按照 Tomcat 的默認設置,在通過 表單 提交的數據將出現亂碼,其原因是中文字符的高位被丟失, 如:

          成龍的 unicode 6210 9f99 ,但是從 request 里面讀出來的是: 10 99

          其原因是 form 表單和 request 方法中設置的編碼格式不一致,在上面,我們已經將頁面編碼改成了 GBK ,因此上,我們只須將 request 的編碼改為 GBK 即可。

          比較簡單的解決方法是,在要用到 request 方法的地方加上這條語句: request.setCharacterEncoding("GBK");

          但這也將遇到與第一種方法同樣,當幾個人同時寫程序時,或者,引用別人已寫的程序的時候,也會存在移植不便的問題。

          更好的方法是,注冊 SetCharacterEncodingFilter 類:

          $TOMCAT_HOME\webapps\your_web_site\WEB-INF\classes 目錄下新建一個名為 filters 的文件夾,然后把 $TOMCAT_HOME\webapps\jsp-examples\WEB-INF\classes\filters SetCharacterEncodingFilter.class 文件拷到新建的 filters 下面,最后在 web.xml 中加入如下的兩個區塊:

          <!-- Example filter to set character encoding on each request -->

          ??? <filter>

          ??????? <filter-name>Set Character Encoding</filter-name>

          ??????? <filter-class>filters.SetCharacterEncodingFilter</filter-class>

          ??????? <init-param>

          ??????????? <param-name>encoding</param-name>

          ??????????? <param-value>GBK</param-value>

          ??????? </init-param>

          ??? </filter>

          ?

          <!-- Example filter mapping to apply the "Set Character Encoding" filter

          ???? to *all* requests processed by this web application -->

          ?

          ??? <filter-mapping>

          ??????? <filter-name>Set Character Encoding</filter-name>

          ??????? <url-pattern>/*</url-pattern>

          ??? </filter-mapping>

          ?????? 如果找不到 SetCharacterEncodingFilter.class ,也可以自己 編寫 SetCharacterEncodingFilter.java 文件,代碼如下:

          *

          ? * filename: SetCharacterEncodingFilter.java

          *

          package filters;

          ?

          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;

          import javax.servlet.UnavailableException;

          ?

          ?

          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 {

          ??????? // Conditionally select and set the character encoding to be used

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

          ??????????? String encoding = selectEncoding(request);

          ??????????? if (encoding != null)

          ??????????????? request.setCharacterEncoding(encoding);

          ??????? }

          ?

          ?????? // Pass control on to the next filter

          ??????? 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 Methods

          ?

          ??? protected String selectEncoding(ServletRequest request) {

          ??????? return (this.encoding);

          ??? }

          ?

          }

          用任意一個 java 編譯器編譯即可,編譯的時候注意包含 servlet-api.jar 包,它位于 $TOMCAT_HOME\common\lib\ 下面。

          ?????? 然后刪除 work 中的內容,然后啟動 Tomcat ,即可顯示中文了。

          三、 數據庫存取亂碼

          當然,在寫數據庫時,也要保正數據庫的編碼與其它一致:

          我們可以在 系統盤 windows 目錄下的 my.ini 文件,在文件中插入一行 default-character-set=GBK, 但上面說了這么多,大家也應該明白些了吧,改動太多的默認設置不是我的風格,因此上,這一行還是不要加的好。

          但不管怎么樣,我們還是要創建一個基于中文編碼的數據庫,當然,用客戶端登錄的時候,某些客戶用自動把字體編碼轉換成中文編碼。在這里,我想說一下在 DOS 下創建中文編碼數據庫的方法:

          在進入數據庫的時候, mysql?--default-character-set=gbk?-u?root?-p? 這句話進入 mysql 然后創建數據庫,如: create?database?admin; 這樣創建起來的數據庫就是基于中文編碼的了。

          用連接數據庫的時候,讀出的數據也可能是亂碼,解決這個問題的方法非常簡單,只要在你建立數據庫連接的時候把 URL 設置成下面這個樣子就可以了: URL=?jdbc:mysql://localhost:3306/my_database?useUnicode=true&characterEncoding=GBK

          好了,說了這么多,總結一句話結束吧,把各種地方的編碼統一起來,那么,所在的亂碼問題就都解決了!

          ?



          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=513467


          評論

          # re: Tomcat5+Mysql文中亂碼問題的解決方法 (轉)  回復  更多評論   

          2007-01-07 11:33 by Zou Ang
          字好大啊

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 石泉县| 辽阳市| 铜鼓县| 浑源县| 靖边县| 贡觉县| 武安市| 甘德县| 酉阳| 德昌县| 双鸭山市| 定兴县| 乐至县| 桦甸市| 鸡泽县| 英山县| 正定县| 六枝特区| 潮安县| 固阳县| 通江县| 沧州市| 玉环县| 陇西县| 西藏| 南京市| 高安市| 广丰县| 监利县| 上高县| 深圳市| 昭通市| 泸西县| 且末县| 千阳县| 宣威市| 荆州市| 西丰县| 吴堡县| 资源县| 兴城市|