Spring本身提供了一套极其优秀的MVC框架,但这套框架的设计过于复杂,采用了大量的映射策略,Struts 2是以Webwork 2作为基础发展出来。而在Webwork 2.2之前的Webwork版本,其自身有一套控制反转的实现,Webwork 2.2在Spring 框架的如火如荼发展的背景下,决定放弃控制反转功能的开发,转由Spring实现。因此,Struts 2推荐通过Spring实现控制反转。
13.4.1 配置应用项目
首先用Myeclipse开发向导创建一个Web应用项目,在本例中创建的项目名为sshapp,然后把下载的struts-2.1.6-all.zip解压包中lib目录中的struts2-spring-plugin-2.1.6.jar、commons-logging.jar,freemarker.jar,ognl.jar,struts2-core.jar,xwork.jar, commons-io-1.3.2.jar ,commons-fileupload-1.2.1.jar (lib目录中Struts 2框架的类库有版本后缀。例如commons-logging.jar,可能是commons-logging-1.0.4.jar;struts2-core.jar可能是struts2-core-2.1.6.jar),加入到项目的WEB-INF\lib目录中,这里需要确保这些包的版本一致,在struts-2.1.6-all.zip解压包中的lib目录中存放的是spring-core-2.0.8.jar包,并没有spring-core-2.5.3.jar,如果用spring-core-2.0.8.jar包,启动Tomcat6时会出现“java.lang.ClassNotFoundException: org.springframework.core.SmartClassLoader”错误提示,可以从struts-2.1.6-all.zip包的apps目录中的struts2-showcase-2.1.6.war包中的WEB-INF\lib目录中找到spring-core-2.5.3.jar包。接下来需要修改WEB-INF\web.xml文件内容,添加内容如下:
<listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class > </listener> |
上面的配置主要是加入Spring的ContextLoaderListener监听器,方便Spring与Web容器交互。紧接着修改Struts.properties文件,以便Struts 2运行时使用Spring来创建对象(如Action等),添加内容如下:
struts.objectFactory =spring |
13.4.2 创建实体表
在MySQL中先创建一个数据库,名称为hibernatedb,然后创建用户表user,创建表的SQL内容如清单13-32所示。
清单13-32
CREATE TABLE hibernatedb.user ( id int(10) NOT NULL auto_increment, name varchar(50) NOT NULL , password varchar(16) NOT NULL , PRIMARY KEY (id) ); |
13.4.3 创建Hibernate框架
在本例中,以前面创建的sshapp项目为基础,来创建Hibernate应用。首先在MyEclipse中选中sshapp项目,然后单击右键,在弹出的菜单中选择MyEclipse项下的项Add Hibernate Capabilites项,弹出如图13-5所示界面,在本例中,选择的Hibernate版本是3.2,其他选择MyEclipse默认的值,然后单击Next按钮弹出如13-6所示按钮,在这里将创建hibernate.cfg.xml配置文件。 MyEclipse中,设置数据库的连接,并将所需的MySQL的jdbc类库拷贝到lib目录中。然后使用MyEclipse的数据Database Explorer向导工具创建User.hbm.xml、User.java映射文件。User.java代码清单13-33所示。
清单13-33
public class User extends AbstractUser implements java.io.Serializable { // Fields private Integer id; private String name; private String password; // Constructors public User() { } // Property accessors public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } } |
User.hbm.xml内容如清单13-34所示。
清单13-34
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.hibernate.bean.User" table="user" catalog="hibernatedb"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="identity" /> </id> <property name="name" type="java.lang.String"> <column name="name" length="50" not-null="true" /> </property> <property name="password" type="java.lang.String"> <column name="password" length="16" not-null="true" /> </property> </class> </hibernate-mapping> |
生成的hibernate.cfg.xml配置文件内容如清单13-35所示。
清单13-35
<?xml version="1.0" encoding="gb2312"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 显示实际操作数据库时的SQL --> <property name="show_sql">true</property> <property name="format_sql">false</property> <property name="cache.use_query_cache">false</property> <!-- SQL方言,这边设定的是MySQL --> <!-- JDBC驱动程序 --> <property name="dialect"> org.hibernate.dialect.MySQLDialect</property> <property name="connection.driver_class"> com.mysql.jdbc.Driver</property> <property name="connection.url"> jdbc:mysql://localhost/hibernatedb </property> <property name="connection.username">root</property> <property name="connection.password">12345</property> <!-- 对象与数据库表格映像文件 --> <mapping resource="ch11/hibernate/User.hbm.xml" /> </session-factory> </hibernate-configuration> |
图13-5 导入Hibernate库 图13-6 创建Hibernate配置
13.4.4 创建DAO
UserDAO接口程序如清单13-36所示。
清单13-36
package com.hibernate.dao; import com.hibernate.bean.User; public interface UserDAO { public abstract boolean isValidUser(String username,String password); public void save(User user); public void delete(User user); public User findById(int id); } |
在创建Hibernate3.2 + Spring2.5+Struts2.1应用程序时,需要相应的类库,应用MyEclipse开发时,可通过开发向导导入所需要的包,具体方法在新建的项目上,单击右键,在弹出的菜单中选择Properties项,弹出如图13-7所示对话框。在对话框中选择Java Build Path项。在右边选择第三个Tab项Libraries,列出了当前项目己添加的类库,要添加MyEclipse中的类库,单击Add Library按钮,弹出如图13-8 所示对话框。在弹出的对话框中选择MyEclipse Libraties项,单击Next按钮,进入MyEclipse Libratis库的选择界面,如图13-9所示。本例选择的类库有Spring 2.5 AOP Libraties、Spring 2.5 Core Libraties、Spring2.0 Persistence Core Libraties和Spring 2.5 Web Libraties。
图13-7 类库配置页面
图13-8 MyEclipse类库 图13-9 选择类库
作者提示:在整合Sping2.5+Struts2.1 +Hibernate3.2中,在启动服务器时会出现java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit导常,这是由于Spring 2.5和 Hibernate 3.2共用的一些 jar 文件发生了版本冲突。解决的办法是在MyEclipse的主菜单Window→Preferences→Myeclipse→Project项中,选择Capabilities→Spring项,从lib中删除asm-2.2.3.jar包即可。如果项目的WEB-INF/lib目录下有asm-2.2.3.jar包,则需要删除该包。
UserDAO接口实现类UserDAOImp代码如清单13-37所示。
清单13-37
package com.hibernate.dao; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import com.hibernate.bean.User; import java.io.Serializable; import java.util.List; import org.hibernate.Query; import org.hibernate.SessionFactory; public class UserDAOImp extends HibernateDaoSupport implements UserDAO { private SessionFactory sessionFactory; private static String hql = "select u from User u where u.name=? and password=? "; public boolean isValidUser(String name, String password) {// 验证登录 String para[] = new String[2]; para[0] = name; para[1] = password; Query query = this.getHibernateTemplate().getSessionFactory() .openSession().createQuery(hql); query.setParameter(0, para[0]); query.setParameter(1, para[1]); List userList = query.list(); try { if (userList.isEmpty()) { return false; } } catch (Exception ex) { ex.printStackTrace(); } return true; } public void save(User user) {// 保存 this.getHibernateTemplate().save(user); } public void delete(User user) {// 删除用户 this.getHibernateTemplate().delete(user); } public User findById(Serializable id) {// 根据ID查找 return (User) this.getHibernateTemplate().get(User.class, id); } public User findById(int id) { return (User) this.getHibernateTemplate().get(User.class, id); } } |
13.4.4 创建Action
接下来修改LoginAction.java代码,使用UserDAO的方法来进行用户验证,代码如清单13-38所示。
清单13-38
package com.struts2.action; import com.hibernate.dao.UserDAO; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport { private static final long serialVersionUID = 1L; private UserDAO userDAO; // 依赖于Spring注入 private String name; private String password; public UserDAO getUserDAO() { return userDAO; } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getPassword() { return this.password; } public void setPassword(String password) { this.password = password; } // 处理用户请求的execute方法 public String execute() throws Exception { System.out.println("执行操作");
if (userDAO.isValidUser(this.getName(), this.getPassword())) { ActionContext.getContext().getSession().put("user", getName()); return this.SUCCESS; } else return this.ERROR;
} // 完成输入校验需要重写的validate方法 public void validate() {// 如果用户名为空,或者用户名为空字符串 System.out.println("校验输入"); if (getName() == null || getName().trim().equals("")) {// 添加表单校验错误 addFieldError("name", getText("user.required")); }// 当密码为空,或者密码为空字符串时,添加表单校验错误 if (getPassword() == null || getPassword().trim().equals("")) { addFieldError("pass", getText("pass.required")); } } } |
上面定义的LoginAction类使用属性(Getter/Setter)注入方法取得userDAO对象。
13.4.5 创建Spring应用
接下来创建Spring的配置文件applicationContext.xml,把该文件存放在项目的WEB-INF目录