String newstr=new String(MM_editQuery.toString().getBytes("8859_1"),"GBK");
PreparedStatement MM_editStatement = MM_connection.prepareStatement(newstr);
基于范例分析的JSP 中文乱码解决方案
JSP 是目前流行的一种动态网站的开发技术,它强大的跨平台的动态网页设计能力受到我国众多程序开发人员的青睐。然而在基于JSP 技术的动态网站开发过程中,由于操作系统、浏览器及数据库所使用的编码方式各异,对中文的支持也不尽相同,如果处理不当,便会出现中文乱码,使开发人员不知所措。JSP 中出现的中文乱码主要可以归结为四种类型:页面乱码、表单传递过程中出现的乱码、读数据库出现乱码和写数据库出现乱码。本文针对这四种类型,设计了尽可能简单又不失一般性的范例,进而分析乱码产生的原因,给出消除乱码的具体方法。
本文的测试环境为:Apache Tomcat 5.5、mysql-4.0.25-win、Navicat 8 for MySQL。如果使用更高版本的mysql,则在安装过程中,
要将字符集Character Set 设为:gb2312(或gbk),并在Navicat 8 for MySQL 中作应用的设置。
1 JSP 页面中文显示出现乱码的处理
【范例设计】hello.jsp,网页的全部代码于下:
<html>
<head><title>我的第一个JSP 网页</title></head>
<body>
<% out.print("你好,JSP! ");%>
</body>
</html>
该网页代码的本意是设计一个标题为“我的第一个JSP 网页”、显示内容为“你好,
JSP! ”的JSP 网页。但除了英文能正常显示外,所有的中文都成了乱码,如图1所示。
【问题分析】JSP 采用ISO-8859-1 作为默认的页面字符编码,这是一种定长单字节字符集,适用于拉丁语,又称Latin-1,不能识别中文。
【解决办法】在网页代码中,加载页面指令
<%@ page contentType="text/html; charset=gb2312" language="java" %>
这就规定了jsp 按其后指定的中文字符集gb2312 编码输出到页面(gb2312 改为GBK 也可以,前者是后者的一个子集,在本文的讨论中,可以不加区别地通用)。
【测试结果】添加了上述页面指令后,再刷新网页hello.jsp,网页标题及内容都正确地显示了相应的中文信息。
说明:如果用Dreamweaver 8 来编写JSP 网页,上述类似的页面指令会默认加载。可以避免出现这种乱码。
2 表单传递过程中乱码的处理
【范例设计】reply.jsp
<%@ page contentType="text/html; charset=gb2312" language="java" %>
<html>
<head><title>表单传送数据</title></head>
<body>
<form id="form1" name="form1" method="post" action="">
请输入用户名:
<input type="text" name="textfield" />
<input type="submit" name="Submit" value="提交" />
</form>
<p>
<% String name=request.getParameter("textfield");
out.print("您的用户名是: "+name); %>
</p>
</body>
</html>
本例含一个由文本框和一个提交按钮组成的表单, 用户在文本框输入信息并
按下提交按钮向服务器提交信息后,服务器立刻将该用户信息返回。如果用户提交
的是英文信息,得到的是正确的返回信息;如果提交的是中文信息,返回的却是乱码。图2,是当用户输入“大学生”后返回的乱码。
【问题分析】由Request.getParameter() 得到的参数,编码方式都是ISO8859_1,直接按这种编码方法显示中文必然得到乱码。
【解决办法】
方法一:
在标记<html>之前,加上一句
:<%request.setCharacterEncoding("GBK");%>
则对于该网页中所有request.getParameter()语句有效。
方法二:
在配置文件server.xml 中,找到含port="8080"的Connector 区块,在其后加一句:URIEncoding="GBK"。修改后的完整信息如下:
<Connector
port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true"/ URIEncoding="GBk">
重启Tomcat 后就OK 了。
此法虽比方法一稍微麻烦一点,但它对网站中所有网页中的request.getParameter()语句有效,可以说是“一劳永逸”。
【测试结果】按方法一或方法二处理后,再在reply.jsp 的表单中输入中文信息,则在下行回显相同的中文信息。这说明表单已经
能够正确地传递中文信息了。
3 读MySQL 数据库中文信息出现乱码的处理
【范例设计】
1)创建数据库sqltest 及表names,表names 只有两个字段(IP 为主键,自动递
增),两条记录(其中一条存放有中文字符)。如表1 所示。
2)建立一个JSP 动态网页show.jsp,按常规方式将表name 在该网页中以动态
表格的形式显示出来,结果是英文信息“zhan san”显示正确,而中文信息“李四”成
了乱码,如图3。
【问题分析】数据库的JDBC 驱动程序,默认的在Java 程序和数据库之间传递
数据都是以ISO-8859-1 为默认编码格式的,即使数据库原本就是用中文编码(如
GBK)格式保存数据的,JDBC 也会自作主张地将其转换为ISO-8859-1 编码格式,
从而导致乱码。
【解决办法】连接数据库时,在url 后面加上“?useUnicode=true&characterEncoding=
GBK”
在本例中,原url 为:jdbc:mysql://localhost:3306/sqltest。
修改后,成为:jdbc:mysql://localhost:3306/sqltest?useUnicode=true&characterEncoding=
GBK
【测试结果】从浏览器端再次访问(或刷新)show.jsp,可见中文信息得到正确显示。
4 写MySQL 数据库时中文信息出现乱码的处理
【范例设计】
在Dreamweaver 中建立一个网页insert.jsp, 它含一个由文本框和一个提交按钮组成的表单,通过加入服务器行为———插入记录,使它具有向上述数据表names插入记录, 并转向能正确显示含中文记录show.jsp 的功能。这样我们就可以通过insert.jsp 插入记录,并由show.jsp 显示结果了。不幸的是当插入中文后,显示的结果却是乱码。如图4、图5 所示,输入“张三”后,显示的却是????。(也可以直接从数据库中证实,保存到表name 中的确实是乱码。)
【问题分析】如前所述,数据库的JDBC 驱动程序在Java 程序和数据库之间传递数据都是以ISO8859-1 为默认编码格式的,程序在向数据库内存储包含中文的数据前,JDBC 首先是把程序内部的Unicode 编码格式的数据转化为ISO8859-1 的格式,然后传递到数据库中,从而导致写入数据库
的中文信息变成了乱码。
【解决办法】赶在ISO-8859-1 的格式编码数据写入数据库之前,将这些数据换成中文编码格式。
具体操作是:查找注释“// finish the sql and execute it”,将其下第三句(也就是执行写数据库操作的前一句):
PreparedStatement MM_editStatement = MM_connection.prepareStatement(MM_editQuery.toString());
改为两句:
【测试结果】再通过网页insert.jsp 插入一条中文记录,show.jsp 则正确地将该记录显示出来,此结果表明insert.jsp 确实将中文信息正确写入到数据库。
说明:笔者发现,当用Dreamweaver 来编辑JSP 动态网页时,凡是涉及写数据库操作,要改的都是本例所指的那句,因此本例具有一般通用意义。
4 结束语
在基于JSP 技术的动态网站开发过程中,不可避免地要字符的编码问题打交道。为了消除出现的乱码,可以有目的地在输入/输出环节中增加必要的转码。其次,由于各种服务器有不同的处理方式,还需要多做试验,确保使用中不出现乱码。
注:
本文作者:刘步星,周赛(长沙电力职业技术学院,湖南长沙410131)
参考文献:
[1] 陈小瀚.中文编码原理及其乱码问题的探讨[J].科技信息:科学教研,2007(24).
[2] 李国禄.JSP 中文乱码问题分析及处理方法[J].甘肃联合大学学报:自然科学版,2007(6).
[3] 伍德雁.Tomcat 应用系统乱码问题研究[J].电脑知识与技术,2008(22).
[4] 蒋军强.MySQL 数据库中乱码成因及解决办法探究[J].科技信息:科学教研,2009(33).