sharky的點(diǎn)滴積累

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            56 隨筆 :: 104 文章 :: 10 評(píng)論 :: 0 Trackbacks

          一、JSP頁(yè)面顯示亂碼
          二、表單提交中文時(shí)出現(xiàn)亂碼
          三、數(shù)據(jù)庫(kù)連
          大家在JSP的開發(fā)過程中,經(jīng)常出現(xiàn)中文亂碼的問題,可能一至困擾著您,我現(xiàn)在把我在JSP開發(fā)中遇到的中文亂碼的問題及解決辦法寫出來供大家參考。

          一、JSP頁(yè)面顯示亂碼
          下面的顯示頁(yè)面(display.jsp)就出現(xiàn)亂碼:
          <html>
          <head>
          <title>JSP的中文處理</title>
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          </head>

          <body>
          <%
          out.print("JSP的中文處理");
          %>
          </body>
          </html>
          對(duì)不同的WEB服務(wù)器和不同的JDK版本,處理結(jié)果就不一樣。原因:服務(wù)器使用的編碼方式不同和瀏覽器對(duì)不同的字符顯示結(jié)果不同而導(dǎo)致的。解決辦法:在JSP頁(yè)面中指定編碼方式(gb2312),即在頁(yè)面的第一行加上:<%@ page contentType="text/html; charset=gb2312"%>,就可以消除亂碼了。完整頁(yè)面如下:
          <%@ page contentType="text/html; charset=gb2312"%>
          <html>
          <head>
          <title>JSP的中文處理</title>
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          </head>

          <body>
          <%
          out.print("JSP的中文處理");
          %>
          </body>
          </html>

          二、表單提交中文時(shí)出現(xiàn)亂碼
          下面是一個(gè)提交頁(yè)面(submit.jsp),代碼如下:
          <html>
          <head>
          <title>JSP的中文處理</title>
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          </head>

          <body>
          <form name="form1" method="post" action="process.jsp">
          <div align="center">
          <input type="text" name="name">
          <input type="submit" name="Submit" value="Submit">
          </div>
          </form>
          </body>
          </html>
          下面是處理頁(yè)面(process.jsp)代碼:
          <%@ page contentType="text/html; charset=gb2312"%>
          <html>
          <head>
          <title>JSP的中文處理</title>
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          </head>

          <body>
          <%=request.getParameter("name")%>
          </body>
          </html>
          如果submit.jsp提交英文字符能正確顯示,如果提交中文時(shí)就會(huì)出現(xiàn)亂碼。原因:瀏覽器默認(rèn)使用UTF-8編碼方式來發(fā)送請(qǐng)求,而UTF-8和GB2312編碼方式表示字符時(shí)不一樣,這樣就出現(xiàn)了不能識(shí)別字符。解決辦法:通過request.setCharacterEncoding("gb2312")對(duì)請(qǐng)求進(jìn)行統(tǒng)一編碼,就實(shí)現(xiàn)了中文的正常顯示。修改后的process.jsp代碼如下:
          <%@ page contentType="text/html; charset=gb2312"%>
          <%
          request.seCharacterEncoding("gb2312");
          %>
          <html>
          <head>
          <title>JSP的中文處理</title>
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          </head>

          <body>
          <%=request.getParameter("name")%>
          </body>
          </html>

          三、數(shù)據(jù)庫(kù)連接出現(xiàn)亂碼
          只要涉及中文的地方全部是亂碼,解決辦法:在數(shù)據(jù)庫(kù)的數(shù)據(jù)庫(kù)URL中加上useUnicode=true&characterEncoding=GBK就OK了。

          四、數(shù)據(jù)庫(kù)的顯示亂碼
          在mysql4.1.0中,varchar類型,text類型就會(huì)出現(xiàn)中文亂碼,對(duì)于varchar類型把它設(shè)為binary屬性就可以解決中文問題,對(duì)于text類型就要用一個(gè)編碼轉(zhuǎn)換類來處理,實(shí)現(xiàn)如下:
          public class Convert {
          /** 把ISO-8859-1碼轉(zhuǎn)換成GB2312
          */
          public static String ISOtoGB(String iso){
          String gb;
          try{
          if(iso.equals("") || iso == null){
          return "";
          }
          else{
          iso = iso.trim();
          gb = new String(iso.getBytes("ISO-8859-1"),"GB2312");
          return gb;
          }
          }
          catch(Exception e){
          System.err.print("編碼轉(zhuǎn)換錯(cuò)誤:"+e.getMessage());
          return "";
          }
          }
          }
          把它編譯成class,就可以調(diào)用Convert類的靜態(tài)方法ISOtoGB()來轉(zhuǎn)換編碼。


          =================================================================

          JSP中的亂碼問題解決方案
          (以下瀏覽器均為IE,服務(wù)器為tomcat)

          服務(wù)器發(fā)送頁(yè)面給瀏覽器時(shí)有兩個(gè)地方指定encoding
          一處是在http應(yīng)答的header里
          一處是在html文檔里

          1.http頭設(shè)置編碼
          若在jsp中request.setContentType("text/html; encoding=gb2312");
          這就明確告訴瀏覽器這篇文檔是gb2312編碼的,瀏覽器不作任何轉(zhuǎn)換,只是以

          gb2312來顯示.若文檔中有8859_1編碼的字串,將會(huì)出現(xiàn)亂碼.

          若jsp中干脆就沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為8859_1,
          瀏覽器通過http頭就認(rèn)為這篇文檔是8859_1編碼的(而不管文檔真正的編碼是什么

          ),會(huì)以8859_1來顯示.
          若文檔中有8859_1編碼的中文字串,只要手動(dòng)調(diào)整瀏覽器的encoding到gb2312,瀏

          覽器會(huì)做一個(gè)8859_1到gb2312的轉(zhuǎn)換,并以gb2312來顯示,你會(huì)看到正確的文字.

          但這樣每次都要手動(dòng)來改變?yōu)g覽器的encoding很麻煩.

          2.在html文檔中設(shè)置編碼
          要讓html文檔中設(shè)置的編碼有效,必須把http頭中的編碼設(shè)為空.
          上文說過,如果jsp中沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為

          8859_1, 這樣一來,瀏覽器還是只認(rèn)http頭中設(shè)置的編碼而不認(rèn)html文檔中設(shè)的編
          但這樣每次都要手動(dòng)來改變?yōu)g覽器的encoding很麻煩.

          2.在html文檔中設(shè)置編碼
          要讓html文檔中設(shè)置的編碼有效,必須把http頭中的編碼設(shè)為空.
          上文說過,如果jsp中沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為

          8859_1, 這樣一來,瀏覽器還是只認(rèn)http頭中設(shè)置的編碼而不認(rèn)html文檔中設(shè)的編

          碼.
          于是,我們?cè)趈sp中來一句
          request.setContentType("text/html; encoding=");
          哈哈,這樣瀏覽器就把文檔默認(rèn)為是8859_1編碼的.
          如果html文檔中有
          <meta http-equiv="Content-Type" content="t會(huì)出現(xiàn)亂碼.

          若jsp中干脆就沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為8859_1,
          瀏覽器通過http頭就認(rèn)為這篇文檔是8859_1編碼的(而不管文檔真正的編碼是什么

          ),會(huì)以8859_1來顯示.
          若文檔中有8859_1編碼的中文字串,只要手動(dòng)調(diào)整瀏覽器的encoding到gb2312,瀏

          覽器會(huì)做一個(gè)8859_1到gb2312的轉(zhuǎn)換,并以gb2312來顯示,你會(huì)看到正確的文字.

          但這樣每次都要手動(dòng)來改變?yōu)g覽器的encoding很麻煩.

          2.在html文檔中設(shè)置編碼
          要讓html文檔中設(shè)置的編碼有效,必須把http頭中的編碼設(shè)為空.
          上文說過,如果jsp中沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為

          8859_1, 這樣一來,瀏覽器還是只認(rèn)http頭中設(shè)置的編碼而不認(rèn)html文檔中設(shè)的編
          但這樣每次都要手動(dòng)來改變?yōu)g覽器的encoding很麻煩.

          2.在html文檔中設(shè)置編碼
          要讓html文檔中設(shè)置的編碼有效,必須把http頭中的編碼設(shè)為空.
          上文說過,如果jsp中沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為

          8859_1, 這樣一來,瀏覽器還是只認(rèn)http頭中設(shè)置的編碼而不認(rèn)html文檔中設(shè)的編

          碼.
          于是,我們?cè)趈sp中來一句
          request.setContentType("text/html; encoding=");
          哈哈,這樣瀏覽器就把文檔默認(rèn)為是8859_1編碼的.
          如果html文檔中有
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          那么瀏覽器就會(huì)做一個(gè)8859_1到gb2312的轉(zhuǎn)換,并以gb2312來顯示.
          由于我們?cè)趈sp中輸出的中文字串都是8859_1編碼的,所有的轉(zhuǎn)換都由瀏覽器來完成的,所以
          我們看到的是正確的文字.

          體會(huì):整篇文檔的encoding必須一致.
          在上文第1種情況中,文檔中編碼不一致,出現(xiàn)亂碼,怎么調(diào)都不行.
          第2種情況中,文檔中的編碼都是一致的,但瀏覽器的顯示方式不對(duì),需手動(dòng)調(diào)整.
          第3種情況中,文檔中的編碼都是一致的(8859_1),瀏覽器的顯示方式也對(duì)了,因此就正確了.

          (以下瀏覽器均為IE,服務(wù)器為tomcat)

          服務(wù)器發(fā)送頁(yè)面給瀏覽器時(shí)有兩個(gè)地方指定encoding
          一處是在http應(yīng)答的header里
          一處是在html文檔里

          1.http頭設(shè)置編碼
          若在jsp中request.setContentType("text/html; encoding=gb2312");
          這就明確告訴瀏覽器這篇文檔是gb2312編碼的,瀏覽器不作任何轉(zhuǎn)換,只是以

          gb2312來顯示.若文檔中有8859_1編碼的字串,將會(huì)出現(xiàn)亂碼.

          若jsp中干脆就沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為8859_1,
          瀏覽器通過http頭就認(rèn)為這篇文檔是8859_1編碼的(而不管文檔真正的編碼是什么

          ),會(huì)以8859_1來顯示.
          若文檔中有8859_1編碼的中文字串,只要手動(dòng)調(diào)整瀏覽器的encoding到gb2312,瀏

          覽器會(huì)做一個(gè)8859_1到gb2312的轉(zhuǎn)換,并以gb2312來顯示,你會(huì)看到正確的文字.

          但這樣每次都要手動(dòng)來改變?yōu)g覽器的encoding很麻煩.

          2.在html文檔中設(shè)置編碼
          要讓html文檔中設(shè)置的編碼有效,必須把http頭中的編碼設(shè)為空.
          上文說過,如果jsp中沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為

          8859_1, 這樣一來,瀏覽器還是只認(rèn)http頭中設(shè)置的編碼而不認(rèn)html文檔中設(shè)的編
          但這樣每次都要手動(dòng)來改變?yōu)g覽器的encoding很麻煩.

          2.在html文檔中設(shè)置編碼
          要讓html文檔中設(shè)置的編碼有效,必須把http頭中的編碼設(shè)為空.
          上文說過,如果jsp中沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為

          8859_1, 這樣一來,瀏覽器還是只認(rèn)http頭中設(shè)置的編碼而不認(rèn)html文檔中設(shè)的編

          碼.
          于是,我們?cè)趈sp中來一句
          request.setContentType("text/html; encoding=");
          哈哈,這樣瀏覽器就把文檔默認(rèn)為是8859_1編碼的.
          如果html文檔中有
          <meta http-equiv="Content-Type" content="t會(huì)出現(xiàn)亂碼.

          若jsp中干脆就沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為8859_1,
          瀏覽器通過http頭就認(rèn)為這篇文檔是8859_1編碼的(而不管文檔真正的編碼是什么

          ),會(huì)以8859_1來顯示.
          若文檔中有8859_1編碼的中文字串,只要手動(dòng)調(diào)整瀏覽器的encoding到gb2312,瀏

          覽器會(huì)做一個(gè)8859_1到gb2312的轉(zhuǎn)換,并以gb2312來顯示,你會(huì)看到正確的文字.

          但這樣每次都要手動(dòng)來改變?yōu)g覽器的encoding很麻煩.

          2.在html文檔中設(shè)置編碼
          要讓html文檔中設(shè)置的編碼有效,必須把http頭中的編碼設(shè)為空.
          上文說過,如果jsp中沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為

          8859_1, 這樣一來,瀏覽器還是只認(rèn)http頭中設(shè)置的編碼而不認(rèn)html文檔中設(shè)的編
          但這樣每次都要手動(dòng)來改變?yōu)g覽器的encoding很麻煩.

          2.在html文檔中設(shè)置編碼
          要讓html文檔中設(shè)置的編碼有效,必須把http頭中的編碼設(shè)為空.
          上文說過,如果jsp中沒有setContentType,服務(wù)器會(huì)把http頭的中的編碼設(shè)為

          8859_1, 這樣一來,瀏覽器還是只認(rèn)http頭中設(shè)置的編碼而不認(rèn)html文檔中設(shè)的編

          碼.
          于是,我們?cè)趈sp中來一句
          request.setContentType("text/html; encoding=");
          哈哈,這樣瀏覽器就把文檔默認(rèn)為是8859_1編碼的.
          如果html文檔中有
          <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
          那么瀏覽器就會(huì)做一個(gè)8859_1到gb2312的轉(zhuǎn)換,并以gb2312來顯示.
          由于我們?cè)趈sp中輸出的中文字串都是8859_1編碼的,所有的轉(zhuǎn)換都由瀏覽器來完成的,所以
          我們看到的是正確的文字.

          體會(huì):整篇文檔的encoding必須一致.
          在上文第1種情況中,文檔中編碼不一致,出現(xiàn)亂碼,怎么調(diào)都不行.
          第2種情況中,文檔中的編碼都是一致的,但瀏覽器的顯示方式不對(duì),需手動(dòng)調(diào)整.
          第3種情況中,文檔中的編碼都是一致的(8859_1),瀏覽器的顯示方式也對(duì)了,因此就正確了.

          =================================================================

          Mysql與JSP網(wǎng)頁(yè)中文亂碼問題的解決方案
          自從以前學(xué)習(xí)JSP開始,中文亂碼問題就一直不斷,苦不堪言。這次在項(xiàng)目開始之前,我們要解決的第一個(gè)問題就是把mysql的中文亂碼問題搞定。經(jīng)過多天的努力,終于成功的解決了中文亂碼問題,特寫在這里,以備后用。

          軟件及環(huán)境:Windows XP(2000), j2sdk1.4.2, Tomcat 5.0.25, mysql 4.1, EMS Mysql Manager 2(方便建表,版本2.8.5.1),驅(qū)動(dòng)為mysql-connector-java-3.1.4-beta-bin.jar。

          目標(biāo):在該環(huán)境下,實(shí)現(xiàn)中文的正常顯示,讀取與插入數(shù)據(jù)庫(kù)。

          注:我只在此環(huán)境下測(cè)試通過,別的系統(tǒng)及不同版本未測(cè)試

          要點(diǎn):統(tǒng)一字符集(JSP頁(yè)面編碼,mysql建庫(kù)時(shí)字符集選擇,連接數(shù)據(jù)庫(kù)URL,request設(shè)定等)

          下面我以GBK為例講解。如果要使用utf-8,只要在相應(yīng)的GBK處換成utf-8即可

          --------------------------- 步驟1 以GBK字符集建庫(kù)建表 -------------------------------------

          我使用EMS來建mysql的數(shù)據(jù)庫(kù)及表,因?yàn)樗菆D形界面,方便操作(就像SQL SERVER 2000中的企業(yè)管理器一樣)。

          建庫(kù)時(shí),從EMS菜單中選create Database...新建一個(gè)數(shù)據(jù)庫(kù),CharacterSet選gbk_bin(另一個(gè)gbk_chinese_ci不知道與這個(gè)有什么區(qū)別,我找資料也沒有找到。如果你知道,請(qǐng)告訴我,我補(bǔ)充在這里)。不要把工具欄上有一個(gè)加號(hào)和數(shù)據(jù)庫(kù)模樣的圖標(biāo)當(dāng)成新建數(shù)據(jù)庫(kù)了,那個(gè)新注冊(cè)一個(gè)已經(jīng)存在的數(shù)據(jù)庫(kù)。
          后面建表時(shí),也要選擇同樣的字符集。

          建好后,此時(shí)不要用EMS向里面插入數(shù)據(jù),否則你看到的中文依然是亂碼。

          --------------------------- 步驟2 連接數(shù)據(jù)庫(kù)的URL后加些參數(shù) -------------------------------

          假設(shè)我新建的數(shù)據(jù)庫(kù)是testdb,那么我連接數(shù)據(jù)庫(kù)的url應(yīng)該為:

          jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=gbk

          此時(shí)要注意:如果我是把這個(gè)url寫在JAVA代碼中,就直接這樣寫。但如果是在xml配置文件中(如struts-config.xml,web.xml等),要把其中的&改為&amp;才行,否則會(huì)出錯(cuò)。也就是:

          jdbc:mysql://localhost:3306/testdb?useUnicode=true&amp;characterEncoding=gbk

          --------------------------- 步驟3 每個(gè)JSP頁(yè)面都要聲明該中文字符集 ----------------------------

          在每個(gè)JSP頁(yè)面的最上面都加上一句

          <%@ page language="java" contentType="text/html;charset=GBK" %>

          這樣才能保證JSP頁(yè)面中的中文顯示正常

          --------------------------- 步驟4 加一個(gè)傳遞參數(shù)時(shí)設(shè)定request字符集的filter類 -----------------------

          因?yàn)榫W(wǎng)絡(luò)中字符在傳遞的時(shí)候,都是統(tǒng)一以iso-8859-1的編碼傳遞,所以我們必須對(duì)request重新設(shè)定字符集,才能正常顯示中文。如果采用filter類來實(shí)現(xiàn),我們不用在每次取中文參數(shù)時(shí)都要重新設(shè)定。

          filter類的內(nèi)容:

          /*
          * ====================================================================
          *
          * JavaWebStudio 開源項(xiàng)目
          *
          * Struts_db v0.1
          *
          * ====================================================================
          */
          package com.strutsLogin.util;

          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 SetCharacterEncodingFilter implements Filter {

          // ----------------------------------------------------- Instance Variables

          /**
          * The default character encoding to set for requests that pass through
          * this filter.
          */
          protected String encoding = null;

          /**
          * The filter configuration object we are associated with. If this value
          * is null, this filter instance is not currently configured.
          */
          protected FilterConfig filterConfig = null;

          /**
          * Should a character encoding specified by the client be ignored?
          */
          protected boolean ignore = true;

          // --------------------------------------------------------- Public Methods

          /**
          * Take this filter out of service.
          */
          public void destroy() {

          this.encoding = null;
          this.filterConfig = null;

          }

          /**
          * Select and set (if specified) the character encoding to be used to
          * interpret request parameters for this request.
          *
          * @param request The servlet request we are processing
          * @param result The servlet response we are creating
          * @param chain The filter chain we are processing
          *
          * @exception IOException if an input/output error occurs
          * @exception ServletException if a servlet error occurs
          */
          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);

          }

          /**
          * Place this filter into service.
          *
          * @param filterConfig The filter configuration object
          */
          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

          /**
          * Select an appropriate character encoding to be used, based on the
          * characteristics of the current request and/or filter initialization
          * parameters. If no character encoding should be set, return
          * <code>null</code>.
          * <p>
          * The default implementation unconditionally returns the value configured
          * by the <strong>encoding</strong> initialization parameter for this
          * filter.
          *
          * @param request The servlet request we are processing
          */
          protected String selectEncoding(ServletRequest request) {

          return (this.encoding);

          }

          }//EOC


          該代碼來自于www.javawebstudio.com,特此感謝!

          然后我們?cè)趙eb.xml中加一些配置,就可以了,配置如下:

          <filter>
          <filter-name>Set Character Encoding</filter-name>
          <filter-class>javawebstudio.struts_db.SetCharacterEncodingFilter</filter-class>
          <init-param>
          <param-name>encoding</param-name>
          <param-value>GBK</param-value>
          </init-param>
          <init-param>
          <param-name>ignore</param-name>
          <param-value>true</param-value>
          </init-param>
          </filter>

          <filter-mapping>
          <filter-name>Set Character Encoding</filter-name>
          <servlet-name>action</servlet-name>
          </filter-mapping>

          放在web.xml的合適位置。一般在最后,<jsp-config>標(biāo)簽之前(如果有的話)

          經(jīng)過以上步驟,JSP和mysql的中文顯示及插入就都正常了。在STRUTS中也正常。

          但是,此時(shí)如果你用EMS或mysql的命令行控制臺(tái)來看表中的數(shù)據(jù),卻發(fā)現(xiàn)它們都是????。這是怎么回事呢?

          不用擔(dān)心,只要我們運(yùn)行下面的這幾行命令,就能看到正常的中文了!

          SET character_set_client = gbk;
          SET character_set_connection = gbk;
          SET character_set_database = gbk;
          SET character_set_results = gbk;
          SET character_set_server = gbk;

          SET collation_connection = gbk_bin;
          SET collation_database = gbk_bin;
          SET collation_server = gbk_bin;

          如果你用的是mysql的命令行,則直接輸入就好。

          如果是EMS,則在工具欄中有一個(gè)Show SQL Editor按鈕,點(diǎn)一下,把上面的命令輸入,再按一個(gè)"execute"的按鈕,就行了!

          而且在這種情況下,你可以甚至可以用中文名來建數(shù)據(jù)庫(kù),表名和字段名!!!!

          ----------------------------------------------------------------------------------------------------

          但是有一點(diǎn)要特別注意!

          像GBK,UTF-8這樣的名字,在mysql與JAVA中有不同的規(guī)定,寫的時(shí)候要格外注意,否則會(huì)出錯(cuò)。

          比如GBK,在JAVA中要寫成GBK,但在mysql中要寫成gbk(連接數(shù)據(jù)庫(kù)的URL)

          比如UTF-8,在JAVA中要寫成UTF-8,但在Mysql中要寫成utf8

          其它的字集符也有類似的區(qū)別

          =============================================================

          告別JSP+MySQL亂碼問題V1.0
          附件:告別JSP+MySQL亂碼問題V1.0.rar

          《JSP數(shù)據(jù)庫(kù)開發(fā)實(shí)例精粹》一書問世以來, 接到許多讀者求救, 其中有80%以上的問題是關(guān)于配置以及亂碼問題,配置問題只要根據(jù)書中視頻依次安裝J2SDK, Tomcat, MySQL(Server+Client),一般都可以解決,但亂碼問題讓許多讀者苦不堪言,現(xiàn)針對(duì)亂碼問題解決如下,相信一定可以將仍困惑在亂碼問題中的讀者解救出來。

          【聲明】:本文僅對(duì)本文所采用的軟件環(huán)境負(fù)責(zé),如果你采用的是其他軟件環(huán)境,只好自己觸類旁通了。
          【版本】:V1.0,最后更新于2005-8-3,請(qǐng)大家認(rèn)準(zhǔn)版本與時(shí)間,如果你是在幾年后看到此文,請(qǐng)不要歉棄老土。^_^

          -----------------------------------------------------------------------
          【軟件環(huán)境】:
              OS: Windows 2000 SP4, Windows XP SP2, 
              JDK:j2sdk-1_4_2_08-windows-i586-p.exe,
              Tomcat: jakarta-tomcat-5.0.28.exe,
              MySQL: mysql-5.0.10a-beta-win32.zip;

          --------------------------------------------------------------------

          【寫在前面的說明】  (必讀):
           1>本文將消除亂碼分為三步:
                  >消除頁(yè)面亂碼,
                  >消除從MySQL中讀出中文亂碼,
                  >消除插入MySQL數(shù)據(jù)庫(kù)中的中文亂碼;

           2>沒有測(cè)試tomcat-5.5. + jdk5,但我想應(yīng)該更容易些吧;

           3>先安裝J2SDK,后裝Tomcat,如果J2SDK安裝在c:\j2sdk1.4.2_08,它同時(shí)會(huì)在C:\Program Files\Java\Jre下安裝一個(gè)public的Jre,在安裝Tomcat時(shí),一定要將JDK指向C:\j2sdk1.4.2_08,否則無法編譯JSP;

           4>注意采用本方法后,操作數(shù)據(jù)庫(kù)時(shí)的相關(guān)中文數(shù)據(jù)無需做額外的字符轉(zhuǎn)換處理,即在所有的字符處理過程中,都以GB2312或GBK來處理;

           5>隨本文發(fā)行的有兩個(gè)純JSP文件和一個(gè)SQL腳本,testCh***t.jsp用來測(cè)試“消除純JSP和HTML頁(yè)面中的亂碼”,tstMySQL.jsp用來測(cè)試“消除從MySQL中讀出中文的亂碼”,均無需手工編譯,放在任一個(gè)Web目錄下即可使用。bookshop.sql為tstMySQL.jsp中用到的數(shù)據(jù)庫(kù),也為《雋雋在線書店》中的更新數(shù)據(jù)庫(kù);

           6>在2k中比在XP中看到亂碼的情況多一些,表現(xiàn)為在2K中meta標(biāo)記不起作用,只能使用page指令,具體原因不太清楚,還望賜教。

           7>關(guān)于MySQL的客戶端功具,個(gè)人習(xí)慣使用MySQL CC,雖然它已不受支持,但本書中全部腳本(使用My SQL數(shù)據(jù)庫(kù)的案例)都可以在MySQL CC中正常運(yùn)行,有些在mysql-query-browser-1.1.13-win.msi出錯(cuò);

           8>從MySQL中讀出的亂碼,如果用MySQL 客戶端顯示正常而在網(wǎng)頁(yè)中亂碼,在確定數(shù)據(jù)庫(kù)連接串中的字符集正確的情況下,把WEB-INF/classes/下,不是你創(chuàng)建的庫(kù)刪除。例如本書《在線書店》就存在此問題,讓W(xué)EB-INF/classes/目錄下只剩bookshop目錄,則可解決亂碼。

           9>每次修改Bean后,最好重啟tomcat,而且最好把Tomcat中Work目錄下的相應(yīng)目錄刪除,否則可能導(dǎo)致你的修改沒有更新,陷入進(jìn)一步的痛苦中……

           10>修改JSP文件無需重啟Tomcat;

           11>用SELECT語(yǔ)句檢索出的數(shù)據(jù),因?yàn)槭褂肕ap緩存數(shù)據(jù),key是區(qū)分大小寫的,應(yīng)統(tǒng)一為大寫或小寫。但SELECT語(yǔ)句與數(shù)據(jù)表之間不區(qū)分大小寫;
            如: 

                strSQL = "SELECT ID, Name FROM BookInfo "
                ……
                rs.getInt("id"); // 錯(cuò)誤
                rs.getInt("ID"); // 正確

           12>新版MySQL中加密密碼不應(yīng)使用password,而應(yīng)使用MD5或 SHA1;本書《醫(yī)院門診》存在此問題,因而無法登錄;

           13>如果使用下面幾步仍不能消除從MySQL中讀出的中文亂碼,把WEB-INF\classes\目錄下非你自己開發(fā)的目錄刪除,此版發(fā)型的《雋雋在線書店》存在此問題;

           14>如果以上方法仍有亂碼存在,應(yīng)該是自己程序的細(xì)節(jié)問題了,比如有些地方特意調(diào)用了編碼轉(zhuǎn)換函數(shù),
               如 uniStr = new String(tempByte,"ISO8859_1");

           15>注意編碼表示方式在JSP與MySQL中的區(qū)別,如下:
               JSP: GB2312, GBK, UTF-8....
               MySQL: gb2312, gbk,  utf8....

          -------------------------------------------------------

          關(guān)鍵問題:編碼,建議統(tǒng)一為GB2312或GBK,本文使用GB2312,GBK未測(cè)試;

          【Step1】: 消除純HTML頁(yè)和JSP頁(yè)在Tomcat環(huán)境下運(yùn)行的亂碼

             這個(gè)是由于流覽器無法選擇編碼方式造成的, 手動(dòng)從IE中選擇“GB2312”即可解決;也可以網(wǎng)頁(yè)中加入META標(biāo)記或Page指令;
             META標(biāo)記如下:
                   <meta http-equiv="Content-Type" content="text/html; charset=GB2312">
             Page指令如下:
                  <%@ page language="java" contentType="text/html; ch***t=GB2312" pageEncoding="GB2312"%>
             前面說明中已經(jīng)提到, META在2K下可能不起作用(XP下時(shí)了時(shí)壞),因?yàn)楹?jiǎn)單起見,加入Page指令似乎是一個(gè)一勞永逸的事情;

             總結(jié): 加入Page指令,一定可以使純JSP頁(yè)面或HTML頁(yè)面在Tomcat環(huán)境下正常顯示。


          【Step2】: 消除從MySQL數(shù)據(jù)庫(kù)中讀出中文的亂碼

              分為兩個(gè)目標(biāo): step1: 從MySQL客戶端查看中文正常, step2: 從網(wǎng)頁(yè)中查看中文正常;

            1: 在用SQL腳本創(chuàng)建數(shù)據(jù)庫(kù)前,設(shè)置MySQL的默認(rèn)編碼方式為“gb2312”,
             此步可以在mysql-administrator-1.1.0-rc-win.msi中完成,或者是MySQL Server向?qū)В?BR>   這樣設(shè)置完畢后再用SQL 腳本創(chuàng)建數(shù)據(jù)庫(kù), 注意如果SQL腳本中有設(shè)置字符集為latin1或utf-8的語(yǔ)句,一定要?jiǎng)h除。
                   已發(fā)現(xiàn)目前版本《在線書店》中的SQL腳本中帶有設(shè)置默認(rèn)字符集為latin1,一定要?jiǎng)h除!

                 創(chuàng)建數(shù)據(jù)庫(kù)完畢后,用MySQL CC或MySQL Admin可檢查所創(chuàng)建的數(shù)據(jù)庫(kù)的字符集,如果正確,則用MySQL CC或MySQL Admin都可以正常查看中文;

            2:  一般情況下,到這一步,在網(wǎng)頁(yè)中已經(jīng)基本能正常顯示中文了,但凡事總有例外,可以在數(shù)據(jù)庫(kù)連接串處再特別說明一下:
                 String url ="jdbc:mysql://localhost/BookStore?useUnicode=true&characterEncoding=gb2312";
                 conn=DriverManager.getConnection(url,"root","");

             一般情況下用 String url ="jdbc:mysql://localhost/BookStore"應(yīng)該就能正常顯示中文。


             總結(jié):修改MySQL Server數(shù)據(jù)庫(kù)默認(rèn)字符集為“GB2312”,從MySQL讀出中文可正常顯示;

             例外: 此時(shí)仍有可能還有亂碼,如本書光盤中的《在線書店》,請(qǐng)參見前面的說明。


          【Step3】: 消除插入MySQL數(shù)據(jù)庫(kù)中的中文亂碼

             此步比較簡(jiǎn)單,在JSP頁(yè)面中加入如下代碼:
                    request.setCharacterEncoding("GB2312");

          ------------------------------------------------------
          THE END, Enjoy it!


          ======================================================

          MySql中文亂碼的解決方法- -
          mysql4.1下,一些數(shù)據(jù)庫(kù)里面的中文會(huì)出現(xiàn)??亂碼現(xiàn)象.因?yàn)?4.1增加了對(duì)utf8的支持,這是件好事.但是,問題是大部分的程序,都是使用的gb2312/gbk這樣的編碼格式,如果把它們都改成utf8格式,要轉(zhuǎn)換成utf8需要解決的事情比較多.編輯器,瀏覽器,mysql-server,mysql-client,php,php-mysql,cvs代碼管理,數(shù)據(jù)庫(kù)備份,還有合適的gb2312到utf8的轉(zhuǎn)換工具.諸多的環(huán)節(jié)需要考慮.
          數(shù)據(jù)庫(kù)的格式轉(zhuǎn)換,文件程序的格式轉(zhuǎn)換,和mysql-server的設(shè)置情況記錄一下.
          當(dāng)然真正的轉(zhuǎn)換,現(xiàn)在還沒有做,現(xiàn)在只是做點(diǎn)規(guī)劃.

          關(guān)于??亂碼,是系統(tǒng)相關(guān)的各個(gè)環(huán)節(jié)之間進(jìn)行代碼轉(zhuǎn)換出現(xiàn)的問題,比如在shell下用mysql這個(gè)程序?qū)?shù)據(jù)庫(kù)進(jìn)行恢復(fù),mysql會(huì)錯(cuò)誤的把代碼進(jìn)行轉(zhuǎn)換,導(dǎo)致亂碼出現(xiàn),

          在轉(zhuǎn)換之前,我們一定要清楚,文件是什么格式,數(shù)據(jù)庫(kù)內(nèi)部是什么格式,都要統(tǒng)一到utf8下來,不對(duì)的要進(jìn)行格式轉(zhuǎn)換.

          1.數(shù)據(jù)庫(kù)的轉(zhuǎn)換.
            以前數(shù)據(jù)庫(kù)里面的字符,應(yīng)該都是gb2312格式,這時(shí),需要把所有的數(shù)據(jù)庫(kù)文件導(dǎo)出成sql文本,然后對(duì)文本進(jìn)行utf-8的格式轉(zhuǎn)換.這里要注意的是一些2進(jìn)值的字段內(nèi)容會(huì)出問題.幸好,在我的項(xiàng)目中,2進(jìn)值內(nèi)容都進(jìn)行了base64編碼,如果數(shù)據(jù)庫(kù)中存在2進(jìn)值的內(nèi)容,就要對(duì)它們進(jìn)行單獨(dú)的處理了.

            用mysqldump把數(shù)據(jù)從mysql4.0中導(dǎo)出,此時(shí)得到的sql文件應(yīng)該是gb2312的,然后用iconv這個(gè)程序把sql文件改為utf8

          導(dǎo)出一個(gè)mysql4.0的庫(kù)(服務(wù)器:192.168.2.2 庫(kù)名:dbname):
          mysqldump -h 192.168.2.2 --add-drop-table -c   --set-charset=latin1 --allow-keywords --force -p  -u root dbname >1.sql
           內(nèi)容轉(zhuǎn)換utf8
          iconv -c -f gb2312 -t utf8 1.sql -o 2.sql

          在導(dǎo)入到4.1之前,先把mysql-server和mysql-client設(shè)置到utf8模式.

          修改/etc/mysq1/my.cnf,在[mysqld]和[mysql]各增加1行:
          [mysqld]
          character_set_server = utf8
          [mysql]
          default-character-set =utf8
          保證讓服務(wù)器端和客戶端都默認(rèn)工作在utf8模式下,重啟mysql-server后就可以導(dǎo)入了.
          mysql -u root -h localhost test <2.sql
          到這里,一個(gè)數(shù)據(jù)庫(kù)就轉(zhuǎn)換完成了.已經(jīng)完全工作在utf8模式下了.

          php的程序的修改.也可以用iconv程序.進(jìn)行.
          首先從cvs導(dǎo)出一個(gè)干凈的代碼拷貝,比如在net目錄下,
          cvs -d :pserver:xxx.xxx.xx.xx net co
          刪除一些不需要轉(zhuǎn)換的文件
          然后執(zhí)行轉(zhuǎn)換
          find . -name "*.php" -type f -exec mv {} {}.old \; -exec iconv --verbose -f gb2312 -t utf8  {}.old  -o  {} \;  -exec  rm  {}.old   \;
          至此,php代碼就批量的轉(zhuǎn)換到utf8模式.還有就是只要修改html的head的語(yǔ)言聲明,從gb2312改成utf8,瀏覽器就會(huì)自動(dòng)使用utf8的模式顯示這個(gè)頁(yè)面.  content="text/html; charset=utf8"

          最后,就是把編輯器改成utf8模式了.這個(gè)就比較簡(jiǎn)單了.

          好了,我們的web應(yīng)用已經(jīng)進(jìn)入utf8模式了.哈哈.


          在使用MYSQL時(shí),插入中文字符,經(jīng)常會(huì)出現(xiàn)亂碼,中文全被用?代替。
              出現(xiàn)這種情況的原因,多是字符集不匹配造成的。
              在MYSQL中,如果使用缺省的字符集,在建庫(kù)、建表時(shí),默認(rèn)使用的是latin1字符集,為ISO 8859-1西歐字符集。
              插入中文字符時(shí),與之不匹配,就會(huì)出現(xiàn)亂碼。
              本人使用的是MYSQL 5.0版,并用C#操作MYSQL數(shù)據(jù)庫(kù),當(dāng)插入中文字符時(shí),發(fā)現(xiàn)顯示的是亂碼。
              初步估計(jì)是字符集沒有配對(duì)。查找后,發(fā)現(xiàn)MSYQL默認(rèn)使用的是latin1,因此將數(shù)據(jù)庫(kù)的配置文件中的字符設(shè)置改為utf8,并在C#中將中文字符,轉(zhuǎn)為utf8,插入后,仍為亂碼。
              MYSQL也支持gb2312,又將MYSQL的字符設(shè)置改為gb2312,C#中使用Default,重起MYSQL后,操作仍然無效。
              后想起,雖然將MYSQL的字符集設(shè)置為gb2312或utf8,但已經(jīng)建立的數(shù)據(jù)庫(kù)和表,仍采用的是默認(rèn)的字符集,也即仍為當(dāng)初的西歐字符集,最好,只得忍痛將數(shù)據(jù)庫(kù)刪除,重新以gb2312字符集建立數(shù)據(jù)庫(kù)和表。
              再用C#插入中文字符后,一切OK。
             
              再安裝好MYSQL后,可以手工或使用配置工具,將my.ini文件中的默認(rèn)字符集改為gb2312,再重新建庫(kù)和表時(shí),不用再在語(yǔ)句中指定字符集,其默認(rèn)設(shè)置也即為gb2312,可以正常顯示中文字符集
          posted on 2005-10-31 21:03 sharky的點(diǎn)滴積累 閱讀(963) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 曲沃县| 类乌齐县| 黎川县| 阳朔县| 平阴县| 积石山| 金塔县| 东海县| 都江堰市| 华池县| 姜堰市| 石楼县| 宜春市| 东海县| 北辰区| 古浪县| 乐都县| 什邡市| 安徽省| 太谷县| 沙坪坝区| 安岳县| 方正县| 巴青县| 安丘市| 区。| 永康市| 文化| 郧西县| 乌兰县| 云梦县| 西宁市| 方山县| 柘荣县| 桂东县| 皋兰县| 怀来县| 吴桥县| 冀州市| 北票市| 万全县|