JSP与MySQL交互的中文乱码解决方案及总结
首先实现了一个StringConvert bean(GBtoISO()和ISOtoGB()两个方法),解决了与MySQL数据库交互的时候的部分中文乱码问题:在JSP程序中读取MySQL的中文内容,用这两个方法可以解决乱码问题。
q/ r; j+ `# }* t
6 Z) |0 P! S2 ^7 ^但是从JSP写入到MySQL的中文内容都成了乱码,并且再读出来的时候也显示为“??”,在这里应该出现了编码转换过程中的字符信息丢失。郁闷的是,我在命令行窗口中登陆到MySQL后,执行如“INSERT INTO customer VALUES(@#字符@#,...)”这样的语句时,写入到数据表中的中文内容又是显示正常的!!!数据库使用的字符集是utf8。
5 b) s+ d/ \, V$ p# H1 g8 i# `/ Q
1 D; Z% R) J# ]2 d$ v, i/ e, C! C6 l7 _* G% e+ K2 O
碰壁多次,终于发现一条解决问题的路径:查看MySQL手册的时候,看到一条这样的语句:To allow multiple character sets to be sent from the client, the "UTF-8" encoding should be used, either by configuring "utf8" as the default server character set, or by configuring the JDBC driver to use "UTF-8" through the characterEncoding property.
3 W2 i$ s' y: e- u6 I% D* k% W3 n8 c
; l% o* l5 e7 q+ i) Q* r& I- S
4 }6 A2 z# Y! M1 U$ V此外,在查阅《MySQL权威指南》时,发现在查询语句中可以使用这样的语法将字符串转换到一个给定的字符集:_charset str。
3 v. G5 n, O- ~* x5 @5 h4 o, ~) o% W6 k
$ p! i6 G( u% W0 z; E5 Z其中charset必须是服务器支持的某个字符集。在本例中,shopdb数据库使用的默认字符集是utf8,于是开始测试: 3 _0 n& H: N7 d3 `8 a
+ i# o) _' N# H先输入INSERT INTO publish Values(@#8@#,_gb2312 @#高等教育出版社@#) 写入后中文变成“??”
9 b0 l8 I+ c# F8 a f! \- v+ z' e" ^+ }* M, m
再试INSERT INTO publish Values(@#8@#,_gbk @#高等教育出版社@#) 结果同上 ) G( y! F2 v9 y( a6 z3 t2 y
6 k7 ]+ M; u# E$ oINSERT INTO publish Values(@#8@#,_utf8 @#高等教育出版社@#) 这下更干脆,什么都没有!!
; S0 c$ r+ q% h' f
6 h1 ]" D8 u* L* o# @( g
W; r( ?" y8 X$ A. ~! b) j! K0 k* h# I
快疯了!!没办法,用show character set;命令查看MySQL支持的字符集,心想我都试一遍总有一个能成功吧。浏览了一下,发现没有几个熟悉的字符集,就只剩下一个latin1(ISO-8859-1)比较常见了,不会是它吧,一试之下果然便是。
* V: J" j( q4 \+ w u
1 @$ P" g# c7 w' C1 EINSERT INTO publish Values(@#8@#,_latin1 @#高等教育出版社@#) 输入中文能够正确显示。
: F7 D Q9 H2 S8 Y% a- t2 S
5 Y! V9 i# M# Q& s* N/ T" M5 K r6 d( y) P' m
) C u& i. _ S4 h4 b3 q
这下总算找到方法了,把Tomcat下配置的数据库连接池的url改为"...characterEncoding=UTF-8",然后把写入数据库的中文内容用 3 g: k _9 |9 b+ j/ D' s: I* T9 [- s
2 r# C- @$ C+ t2 e7 eString s2 = new String(s1.getBytes("gb2312"),"ISO-8859-1")进行转码,其中s1为中文字符串.然后再写入到数据库一切显示正常。 # V2 ~* @! O. x1 f3 [
2 `2 n7 q* G; |7 Y8 K; N& B; e" J& j3 U$ j& B& g( _; s {
' ?" K- K) u! L; p$ ]
为解决这个问题查看了n多资料,现作一个总结:由于字符集和字符编码方式的不同,在OS以及程序之间传递数据(尤其是multiple character sets中的数据)时便会产生乱码以及字符信息的丢失.解决这个问题的关键便是了解数据输出端和接收端使用的字符集和字符编码方式,如果这两种编码方式不同,便需要在数据出口或入口处进行 转码。一般的说,在编写代码,编译,以及运行期间都会字符数据的传递,因此需要特别小心。 9 |3 m( S1 l" H
) t( G1 n$ a- ?, Y 在编写代码的时候,你可能会使用某种开发工具,例如我正在使用的Eclipse.或许在写的时候一切正常,可是一旦保存后再次打开文档,所有的中文字符都变成了乱码。这是因为在编写的时候,这些字符数据都在内存的某个stream中,ok,这没问题,可是保存的时候这个stream中的数据会被写入到硬盘,使用的就是你的开发工具默认的编码方式,如果很不幸你的开发工具默认编码方式是ISO-8859-1,中文字符信息就不能正确地存储。Eclipse中可以这样查看并修改默认字符编码方式:Project->Properties->info,这里有"default " b; e0 a, N" B, f S- o
encoding for text file"。如果设置为GBK,那么编写代码并保存这关就过了。
0 T, F/ y( o# e: J2 k4 H2 A( Y, d$ V! X* u
对于JSP程序而言,编写完代码后就交给Container,首先它们会被转成.java文件,然后编译成.class才能提交给服务器执行.这个过程也存在字符编码问题.java编译器(javac)使用操作系统的语言环境作为默认的字符编码方式,JRE(Java Runtime Environment)也是这样。只有当编译和运行环境的字符编码方式与存储源文件的编码方式相同时,中文字符才能正确地显示。否则就需要在运行时进行转码,使它们使用兼容的编码。这里的设置可以分为几个层次:操作系统层支持的语言,这是最重要的,因为它会影响JVM的默认字符编码方式,同时对字符的显示,如字体等有直接影响;J2EE服务器层,大多数服务器都可以对字符编码进行自定义的配置,例如Tomcat就可以通过web.xml中设置javaEncoding参数设置字符编码,默认是UTF-8. b) G+ _3 o' n% L
$ W( I6 f* w% K6 H" m! @- ^IE也可以设置成总是使用UTF-8编码来发送请求.应用程序层,每个配置在服务器下的程序都可以设置自己的编码方式,这个我目前还没有用到,以后再学习。
- B4 o9 _1 J* G7 I0 Y' n- ^
9 l/ S9 w5 f# l 运行时的转码,运行时期,应用程序很可能需要与外部系统进行交互,例如对数据库进行读写,对外部文件进行读写.在这些情况下,应用程序免不了要和外部系统进行数据交换。那么对于中文字符, 数据出入口的编码方式就显得特别重要了。一般外部系统都有自己的字符编码方式,我的例子中配置的MySQL就是使用的UTF-8编码。JSP页面通过设定"charset=gb2312", ( l: n6 a; t6 O/ i: h3 f6 ~
" F! V6 i! b0 x+ D3 Z% d% n. V使用gb2312编码,在它与数据库交互的时候就需要进行显式的转码才能正确处理中文字符。