JSP和Servlet对中文的处理过程(7)

http://www.itjxue.com  2015-07-17 08:27  来源:未知  点击次数: 

如果不指定Compile-charset或Servlet-charset,其默认值均为ISO8859-1。

当Compile-charset=Servlet-charset时,第2步和第4步能互逆,“抵消”,显示结果均能正确。读者可试着写一下Compile-charset<>Servlet-charset时的情况,肯定是不正确的。

当输出对象是数据库时

输出到数据库时,原理与输出到浏览器也是一样的。本节只是Servlet为例,JSP的情况请读者自行推导。

假设有一个Servlet,它能接收来自客户端(IE,简体中文)的汉字字符串,然后把它写入到内码为ISO8859-1的数据库中,然后再从数据库中取出这个字符串,显示到客户端。

表9 输出对象是数据库时的变化过程(1)

序号
步骤说明
结果

1
在IE中输入“中文”
D6 D0 CE C4
IE

2
IE把字符串转变成UTF,并送入传输流中
E4 B8 AD E6 96 87

3
Servlet接收到输入流,用readUTF读取
4E 2D 65 87(unicode)
Servlet

4
编程者在Servlet中必须把字符串根据GB2312还原为字节流
D6 D0 CE C4

5
编程者根据数据库内码ISO8859-1生成新的字符串
00 D6 00 D0 00 CE 00 C4

6
把新生成的字符串提交给JDBC
00 D6 00 D0 00 CE 00 C4

7
JDBC检测到数据库内码为ISO8859-1
00 D6 00 D0 00 CE 00 C4
JDBC

8
JDBC把接收到的字符串按照ISO8859-1生成字节流
D6 D0 CE C4

9
JDBC把字节流写入数据库中
D6 D0 CE C4

10
完成数据存储工作
D6 D0 CE C4 数据库

以下是从数据库中取出数的过程

11
JDBC从数据库中取出字节流
D6 D0 CE C4
JDBC

12
JDBC按照数据库的字符集ISO8859-1生成字符串,并提交给Servlet
00 D6 00 D0 00 CE 00 C4 (Unicode)

13
Servlet获得字符串
00 D6 00 D0 00 CE 00 C4 (Unicode)
Servlet

15
编程者必须根据数据库的内码ISO8859-1还原成原始字节流
D6 D0 CE C4

16
编程者必须根据客户端字符集GB2312生成新的字符串
4E 2D 65 87

(Unicode)

Servlet准备把字符串输出到客户端

17
Servlet根据生成字节流
D6 D0 CE C4
Servlet

18
Servlet把字节流输出到IE中,如果已指定,还会设置IE的编码为
D6 D0 CE C4

19
IE根据指定的编码或默认编码查看结果
“中文”(正确显示)
IE


解释一下,表中第4第5步和第15第16步是用红色标记的,表示要由编码者来作转换。第4、5两步其实就是一句话:“new String(source.getBytes("GB2312"), "ISO8859-1")”。第15、16两步也是一句话:“new String(source.getBytes("ISO8859-1"), "GB2312")”。亲爱的读者,你在这样编写代码时是否意识到了其中的每一个细节呢?

至于客户端内码和数据库内码为其它值时的流程,和输出对象是系统控制台时的流程,请读者自己想吧。明白了上述流程的原理,相信你可以轻松地写出来。

行文至此,已可告一段落了。终点又回到了起点,对于编程者而言,几乎是什么影响都没有。

因为我们早就被告之要这么做了。

以下给出一个结论,作为结尾。

1、 在Jsp文件中,要指定contentType,其中,charset的值要与客户端浏览器所用的字符集一样;对于其中的字符串常量,不需做任何内码转换;对于字符串变量,要求能根据ContentType中指定的字符集还原成客户端能识别的字节流,简单地说,就是“字符串变量是基于字符集的”;

2、 在Servlet中,必须用HttpServletResponse.setContentType()设置charset,且设置成与客户端内码一致;对于其中的字符串常量,需要在Javac编译时指定encoding,这个encoding必须与编写源文件的平台的字符集一样,一般说来都是GB2312或GBK;对于字符串变量,与JSP一样,必须“是基于字符集的”。

(责任编辑:IT教学网)

更多

推荐JSP教程文章