您的位置:首页 > 编程语言 > Java开发

实例解析Struts 2.1与Sping、Hibernate集成

2009-03-10 00:56 633 查看
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目录下,配置内容如清单13-39所示。
清单13-39

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.1.xsd"> <!-- Hibernate设置 -->
<!-- 会话工厂设置,读取Hibernate数据库配置信息 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
<!--直接引入Hibernate配置方法 -->
</property>
</bean>
<!-- Spring设置 -->
<!-- 会话模板 -->
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!-- 配置UserDAOImpl持久化类的DAO bean-->
<bean id="userDAO" class="com.hibernate.dao.UserDAOImp">
<!--采用依赖注入来传入SessionFactory的引用-->
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<!-- 配置事务拦截器-->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 事务拦截器bean 需要依赖注入一个事务管理器-->
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="transactionAttributes">
<!-- 下面定义事务传播属性-->
<props>
<prop key="save">PROPAGATION_REQUIRED</prop>
<prop key="dele*">PROPAGATION_REQUIRED</prop>

</props>
</property>
</bean>
<!--定义BeanNameAutoProxyCreator ,该bean 是个bean 后处理器,无须被引用,因此
没有id 属性,这个bean 后处理器,根据事务拦截器为目标bean 自动创建事务代理-->
<bean class ="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!--指定对满足哪些bean name 的bean 自动生成业务代理-->
<property name="beanNames">
<!-- 下面是所有需要自动创建事务代理的bean-->
<list>
<value>userDAO</value>
</list><!-- 此处可增加其他需要自动创建事务代理的bean-->
</property>
<!--下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
<!-- 设置代理Struts动作 -->
<bean name="loginAction" class="com.struts2.action.LoginAction"
scope="prototype">
<property name ="userDAO">
<ref local ="userDAO" />
</property>
</bean>
</beans>
在上面的配置中,Struts 2会为每一个请求创建一个Action对象,所以在定义LoginAction时应用scope="prototype"属性。这样Spring会为每个调用者返回一个新的LoginAction对象。 因为userDAO被配置为默认的scope(也即是singleton,单根模式),所以在实现时应保证其线程安全。
上面定义的Action在struts.xml中的配置内容如清单13-41所示。
清单13-41

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<include file="struts-default.xml" />
<package name="Spring" extends="struts-default">
<action name="loginaction" class="loginAction">
<result name="success">/index.jsp</result>
<result name="error">/sshlogin.jsp</result>
<result name="input">/sshlogin.jsp</result>
</action>
</package>
</struts>
这里的Action 配置与前面不同的就是class属性,它对应于Spring所定义的bean的id,而不是它的类全名。

13.4.6 测试部署应用

最后,定义一个显示用户列表的JSP文件sshlogin.jsp,实现代码如清单13-42所示。
清单13-42

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<html>
<head>
</head>
<body>
<!-- 提交请求参数的表单 -->
<form action="loginaction.action" method="post" >
<table align="center">
<caption>
<h4>用户登录信息</h4>
</caption>
<tr><!-- 用户名的表单域 -->
<td>用户名:<input type="text" name="name" /></td></tr>
<tr><td>密 码 :
<input type="password" name="password" style=" width : 149px;"/>
</td></tr>
<tr align="center">
<td colspan="2">
<input type="submit" value="登 录" />
<input type="reset" value="清 除" />
</td></tr>
</table>
</form>
</body>
</html>
发布应用程序后,在浏览器地址栏中输入http://localhost:8081/sshapp/sshlogin.jsp,程序运行页面如图13-10所示。为了测试登录功能,可以先在前面创建的User表中录入一些用户信息,然后在如图13-10所示登录页面中测试。

图13-10 登录页面
上面的应用程序介绍了一个简单的登录程序,演示如何整合Spring2.5、Hibernate3.2、Struts2.1三种技术。在本例中,应用Spring2.5作为整个系统的控制容器,Struts2.1与Hibernate3.2在Spring2.5的控制容器中工作。

转自http://blog.csdn.net/tfnew21/archive/2009/03/09/3974403.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: