37.6 解决Tomcat的中文问题(V008)
在本例修改用户的姓名时,会出现中文乱码问题。过去很多人在Web编程中都是用字符编码转换函数来解决中文问题,其实没有必要这么麻烦。本节给出Tomcat中文问题的一个方便的解决方案,不必使用编码转换函数,即可将其中文问题彻底解决(假设读者已经做好了MySQL数据库的字符集设置,参阅25.4节)。
(1)将%TOMCAT_HOME%/webapps/jsp-examples/WEB-INF/classes/filters目录中的两个Java源程序RequestDumperFilter.java、SetCharacterEncodingFilter.java复制到cn.com.chengang.sms包下(放在其他包也可),然后将两源程序的包定义改为“package cn.com.chengang.sms;”。
(2)修改myweb项目的WEB-INF/web.xml,在<display-name>项和<servlet>项之间加入以下配置。注意,如果将以下配置加入到web.xml的其他位置,会导致Eclipse报错,这是因为web.xml文件头设置的DTD文件限定了各项的顺序。
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>cn.com.chengang.sms.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(3)以后编写JSP文件时,记得像本书一样加入下面两句:
<%@ page contentType="text/html; charset=utf8"%>
<META http-equiv=Content-Type content="text/html; charset=utf8">
(4)本书第1版是采用GBK编码,这一版转为采用UTF8编码。如果读者在以后实际开发中采用GBK编码,则把本书所有utf8之处改为GBK即可。
37.7 Web的打包发行
打包方法:在J2EE透视图中右击myweb项目,选择右键菜单的“导出→WAR files”命令,在弹出页面(图37.8)填写导出目录及文件名“D:/myweb.war”,单击“完成” 按钮。
部署方法:将导出文件myweb.war复制到%TOMCAT_HOME%/webapps目录即可。
myweb.war实际上是一个ZIP格式的压缩包,而导出操作实际上是将项目的相关文件打在一个压缩包中的过程。在实际项目中,一般都是用Ant或Maven这类脚本工具来完成打包压缩过程,打包文件的目录结构参考myweb.war,如图37.9所示。
图37.8 导出设置 图37.9 myweb.war的目录结构
37.8 Hibernate的自动生成工具
在37.4节给出的XML映射文件设置口诀:“以实体类的字段为依据来配置XML映射文件:类的字段有则映射有、类的字段无则映射无”,这实际上是“实体类↔XML映射↔数据库表”这3者之间对应关系的一个反映。通过本节的学习,读者会发现,这3者之间是可以互相用工具来转化的。
37.8.1 由XML映射文件生成数据库表(V009)
Hibernate可以由XML映射文件自动生成数据库表,这简化了创建表格的工作。具体实现方法如下:
(1)将以下两种方法添加到HibernateUtil类中。
// 创建数据库表。如果表存在将会被删除重建,同时sql语句输出到c:/sms.sql
public static void createDbTable() throws HibernateException {
Configuration conf = new Configuration().configure();
SchemaExport dbExport = new SchemaExport(conf);
dbExport.setOutputFile("c://sms.sql");
dbExport.create(true, true);
}
// 增量式更新数据库表。
// (1)会将XML映射文件中新增的字段加入到表中,表的原数据不会被抹掉。
// (2)这种更新是通过字段来判断的,如果表字段和XML映射文件字段同名,
// 但类型和长度不同,表中的字段类型和长度也不会被更新。
// (3)如果表中的字段在XML映射文件中没有定义,此表字段也不会被删除。
public static void updateDbTable() throws HibernateException {
Configuration conf = new Configuration().configure();
new SchemaUpdate(conf).execute(true, true);//增量
}
(2)在myweb项目中创建一个名为createDbTable.jsp的JSP页面来调用上面的两种方法。其代码如下:
<%
cn.com.chengang.sms.db.HibernateUtil.createDbTable();
//cn.com.chengang.sms.db.HibernateUtil.updateDbTable();
%>
%注意:运行createDbTable.jsp之前要保证已经存在了sms库,否则会出错。本操作自动会将sms库的所有表都删除重建。重建表之后的初始数据需要另外再导入,否则网页无法登录,导入初始数据可参阅26.5节。
打开地址“http://localhost:8080/myweb/createDbTable.jsp”,网页执行后无显示,但控制台会有输出,并且数据库表已经产生变化。如图37.10所示,schoolclass表的name字段的长度由20改成了255。
图37.10 Hibernate自动创建的表
可以重新修改XML映射文件model.hbm.xml,加入更多属性来定义一个字段,否则Hibernate对没有定义的属性(比如字段长度)会自动使用默认值。
37.8.2 使用Hibernate Tools
在下载Hibernate时,顺带也下载了Hibernate Tools,它是一个用于辅助Hibernate开发的Eclipse插件。其安装方法和其他Eclipse插件一样,本书不再复述,下面主要谈谈如何使用它。
1.在myweb项目创建一个专用于Hibernate Tools的目录test
2.创建Hibernate配置文件
之前已经创建了一个Hibernate配置文件hibernate.cfg.xml,不过这个hibernate.cfg.xml中的数据库配置是用Tomcat的DataSource。Hibernate Tools不认这种数据库配置,无法连接到数据库,所以不得不再创建一个hibernate2.cfg.xml。
创建hibernate2.cfg.xml的方法是:选择主菜单“文件→新建→其他”命令;在新建向导窗口的第一页选择“Hibernate Configuration File(cfg.xml)”项,单击“下一步”按钮;在第二页的设置如图37.11所示;在第三页的设置如图37.12所示。
图37.11 输入文件名和所在目录 图37.12 数据库相关设置
这时在项目新建的test目录下生成了一个hibernate2.cfg.xml文件,其内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/sms</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
</session-factory>
</hibernate-configuration>
3.创建“Hibernate Console Configuration”来连接数据库
创建一个“Hibernate Console Configuration”的方法是:选择主菜单“文件→新建→其他”命令;在新建向导窗口的第一页选择“Hibernate Console Configuration”项,单击“下一步”按钮;在新窗口General选项卡的设置如图37.13所示;Classpath选项卡的设置如 图37.14所示,注意第二项是JDBC连接包的地址%TOMCAT_HOME% /common/lib/mysql-connector-java -5.0.4-bin.jar。最后单击“完成”按钮,如弹出对话框则选择“是”。
图37.13 General选项卡 图37.14 Classpath选项卡
打开“Hibernate Console”透视图,可以看到创建的“Hibernate Console Configuration”—— myweb_console,其Database结点显示了数据库sms的各表。如图37.15所示,选择右键菜单的“Edit Configuration”命令可以返回图37.13重新配置myweb_console。
%注意:对myweb_console的不慎修改,可能会导致Eclipse崩溃,这时强行关闭Eclipse后,再次打开即可。
图37.15 “Hibernate Console”透视图
4.根据数据库表自动生成Java类、XML映射文件、DAO访问类
操作如图37.16所示,选择“Hibernate Code Generation”命令,打开如图37.17所示的运行窗口;用右键菜单在左部的结点树新建一个结点,在右部顶头的“名称”处将新建结点改名为myweb_console,其他的设置参照图37.17和图37.18。
图37.16 Hibernate Tools的运行 图37.17 Hibernate Tools的运行窗口——Main选项卡
设置完后单击“运行”按钮。在test目录中产生了图37.19所选的文件。其中产生的目录结构对于源代码来说就是一个包cn.com.chengang.sms.model,这是由图37.17中的Package项来设置的。图37.19导出的文件分成3大类:
● *.java——和数据库表对应的数据模型。选中图37.18中的“Domain Code”复选框可以产生这些代码。
● *.hbm.xml——XML映射文件。选中图37.18中的“Hibernate XML Mappings”复选框可以产生这些代码。
● *Home.java——DAO类。它类似于本实例的DbOperate类,主要提供了一些访问数据库的方法,可以把它们的代码合并到DbOperate类中。
图37.18 Exporters选项卡 图37.19 导出的文件
5.由XML映射文件产生数据表
这一步实现的功能和第37.8.1节的一样,只不过这次是用Hibernate Tools插件的GUI操作来实现。实现的方法是:选择图37.21中的“Edit Configuration”命令;在弹出窗口中选择Mappings选项卡(图37.20);再把一个或几个XML映射文件加入到列表中,这里加入的是实例以前创建的model.hbm.xml。再次打开图37.21中的右键菜单,“Run SchemaExport”命令由无效变为有效,选择它。
以上操作完成之后,Hibernate Tools插件将根据图37.20中的*.hbm.xml设置在数据库创建相应的表,如果数据库存在同名的表将被覆盖。另外,图37.21中的Configuration和Session Factory结点都将显示出model.hbm.xml中相应的类配置信息。
如果以上操作导致Eclipse崩溃,须强行关闭Eclipse,然后再打开。如果Session Factory结点下没有显示,可选择主菜单“项目→清理”命令,再重启Eclipse。
图37.20 Mappings选项卡 图37.21 myweb_console的右键菜单
6.执行HQL语句
选择图37.21中的“HQL Eitor”命令,可以打开一个如图37.22所示的编辑器,输入一条最简单的HQL语句“form IUser”,再选择图中最左边的三角形图标来运行HQL语句。
HQL语句运行后,得到图37.23所示的数据对象列表。图中的中文显示不出来,这也算是Hibernate Tools的一个小BUG,对国际化支持不够好。
%注意:如果执行了第5步的“Run SchemaExport”,数据库表将全部被覆盖,这时IUser表就没有数据了,因此得不到图37.23所示的结果。这时需要向IUser表中加入一些数据,或者参考26.4节和26.5节创建表并重新导入数据。
图37.22 HQL Editor
图37.23 HQL语句“form IUser”的结果