JSP中文问题浅析

时间:2022-08-12 12:48:25

JSP中文问题浅析

摘要:JSP是目前比较热门的一个话题,它继承了Java的所有优点。可是在编写JSP程序的过程中,常遇到中文乱码问题,而且使用平台不同,中文乱码问题的解决方法也不同,无形中增加了学习JSP的难度。在此,通过剖析其产生原因后,提出了相应的解决方法,并归纳出几点结论。

关键词:JSP;中文问题;Unicode

中图分类号: TP311 文献标识码: A文章编号:1009-3044(2008)33-1367-02

Slight JSP Chinese problem

HUANG Ji,JIANG Li-qun

(College of Computer, China University of Mining and Technology, Xuzhou 221008, China)

Abstract: JSP is a pop topic at present ,it inherited all excellence of Java .But we often meet the problem of Chinese problem ,at the time of writing JSP program, furthermore ,in different instance ,the ways of solving are different , this increase the difficulty of learning JSP. So, by analyzing the cause of it, put forward relevant solving methods, and conclude some conclusion.

Key words:JSP; Chinese problem; Unicode

1 JSP中文问题的由来

Java的内核和class文件是基于Unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首先JSP(包括Java)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class 文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。

其次Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,(注:从char到byte是编码的过程,反之,是解码的过程。)具体情况如下:

Byte型

Char型

页面form提交(数据)-> JSP程序(java程序)

数据库(数据)

-> JSP程序(java程序)

文件(数据)

-> JSP程序(java程序)

流(数据)

-> JSP程序(java程序)

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。 为了进一步了解编码和解码之间的关系,下面我们解释一下字符编码相关知识。

每个国家(或区域)都规定了计算机信息交换用的字符编码集,如美国的扩展ASCII码、中国的GB2312-80、日本的 JIS 等,作为该国家(区域)信息处理的基础,有着统一编码的重要作用。由于各本地字符集代码范围重叠,相互间信息交换困难,软件本地化版本独立维护成本较高。因此有必要将本地化工作中的共性抽取出来,做一致性处理,将特殊的本地化处理内容降低到最少,这就是所谓的国际化。各种语言信息被规范为本地信息,而底层字符集采用包含了所有字符的Unicode。

字符内码(character code)指的是用来代表字符的内码。我们在输入和存储文档时都要使用内码,内码分为单字节内码和双字节内码。单字节内码的英文全称是Single-Byte Character Sets (SBCS),可以支持256个字符编码;双字节内码的英文全称是Double-Byte Character Sets(DBCS),可以支持65000个字符编码,主要用来对大字符集的东方文字进行编码。

CodePage指的是一个经过挑选的以特定顺序排列的字符内码列表,对于早期的单字节内码的语种,CodePage中的内码顺序使得系统可以按照此列表来根据键盘的输入值给出一个对应的内码。对于双字节内码,给出的是Multiyear到Unicode的对应表,这样就可以把以Unicode形式存放的字符转化为相应的字符内码。引入对CodePage的支持主要是为了访问多语种文件名,目前在NTFS和FAT32/VFAT下的文件系统上都使用Unicode,这需要系统在读取这些文件名时动态地将其转换为相应的语言编码。

2 解决方法

解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,以下总结了几条解决的方法。

2.1 对于JSP页面显示乱码

解决的方法是:在JSP页中加入一条语句:

gb2312" %>或[1]中文显示就正常了。(注:此语句必须先加入,然后输入中文,如果输入中文保存之后,再加入此语句仍可能产生乱码,因为编译时已经开始编码。)对于频繁的转换我们可以编写一个方法,以共调用,如下:

public String getStr(String str)

{

try

{

String temp_p=str;

byte[] temp_t=temp_p.getBytes("ISO8859_1");

String temp=new String(temp_t,"GB2312");

return temp;

}

catch(Exception e)

{ return "null";}

}

2.2 对于JSP页面参数之间的乱码

JSP获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式: request.setCharacterEncoding("GBK")或request.setCharacterEncoding ("gb2312")。如果在JSP将变量输出到页面时出现了乱码,可以通过设置response.setContentType("text/html;charset=GBK")或response.setCo

ntentType("text/html;charset= gb2312")解决。

2.3 对于数据库的显示乱码

对于将中文数据写入数据库的问题,采取的方式就不同了:

windows下,必须要采用该字符串转换再插入数据库,而Linux下就不需要,而是直接把8859_1编码的字符插入。

如果从数据库中读出的数据,对于windows因为在插入时已经做了转换,所以读出时已经是gb2312的,当把它显示在网页上时,不需要做编码转换,而Linux上的Mysql中的数据是8859_1的所以要做编码的转换。

2.4 对于数据库连接的乱码

可以对中文字符进行相应的编码解码,不过,有一种比较好的方法是在连接数据库的时候指定编码(以Mysql为例):String sConnStr="jdbc:mysql://localhost/test?user=xxx&password=yyy&useUnicode=true&characterEncoding=8859_1"。[2]

2.5 文件/流的乱码

Java读写文件最常用的类是 FileInputStream/FileOutputStream和FileReader/File

Writer。其中FileInputStream 和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和 FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用FileReader和FileWriter的父类: InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型: InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter (OutputStream out, Charset cs) [3]。

2.6 其它

对于javabean,在编译javabean时 javac 命令行加上-encoding ISO8859_1。

对于Servlet, 在dopost或者doget的第一句加上:

request.setCharacterEncoding("gb2312");

response.setCharacterEncoding("gb2312");

也可以在编译Servlet和JSP时加入代码选项。在编译Servlet时使用Java-Encoding ISO8859-1 myservlet.java;(其中myservlet.java是要编译的文件)在JSP的ZONE配置文件中,修改编译参数为:Compiler=builtin - javac- encoding ISO8859-1。使用这种方法后,不需要做其他的改动就可以正常显示中文了。

3 结论

1)在JSP中如果指定了,那么在改JSP中所有构造的String(不是引用),如果]有指定编码,那么这些String的编码是GBK的。

从request的得到的String如果]有指定request的编码的话,他是iso-8859-1.从别的地方得到的String是使用原来初始的编码的,比如从数据库得到String,如果数据库的编码是UTF-8,那么该String的编码是UTF-8而不是GBK的,也不是系统默认的。此时,如果要输出的String的编码不是GBK,那么,很可能显示乱码的,所以首先要将String正确转化为编码GBK的String,然后输出。

2)在JSP中没有指定,那么相当于指定了。[1]

3)Servlet中如果执行了像 response.setContentType ("text/html;

charset=GBK");h明将response的字符输出流编码设置为GBK,所有要输出的String的编码要转化为GBK的,否则会得到乱码的。

Servlet中从request得到的String的编码和JSP中一样的,但是在Servlet java文件中构造的String是使用的系统默认的编码的。在Servlet中从外部得到的String 是使用原来的编码的,比如从编码为UTF-8的数据库得到的数据是编码为UTF-8的,不是GBK,也不是系统默认的编码。

另外,对于不同的数据库如SQL Server,Oracle,Mysql,Sybase等,字符集的选择很重要。如果考虑多语言版本,数据库的字符集就应该统一采用ISO8859-1,需要输出的时候在不同的字符集之间做转换就可以了。

参考文献:

[1] 柳永坡. JSP 应用开发技术[M].北京:人民邮电出版社,2005(9).

[2] 刘彬 . JSP 数据库高级编程[M].北京:清华大学出版社,2006(3).

[3] 朱剑平,刘颖. Java 语言计算机科学与程序设计[M].北京:清华大学出版社, 2005.

上一篇:微机原理与接口教学方法探讨 下一篇:普通地方高校信息管理与信息系统专业本科课程...