一、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ì)了,因此就正確了.
=================================================================
自從以前學(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等),要把其中的&改為&才行,否則會(huì)出錯(cuò)。也就是:
jdbc:mysql://localhost:3306/testdb?useUnicode=true&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數(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!
======================================================
數(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,可以正常顯示中文字符集