标签:struts2 spring hibernate 框架整合 s2sh框架整合
新建项目s2sh:
添加如下的jar包:
commons-fileupload-1.2.2.jar
commons-io-2.0.1.jar
freemarker-2.3.19.jar
ognl-3.0.5.jar
struts2-core-2.3.4.1.jar
xwork-core-2.3.4.1.jar
疑惑:这些jar可以从哪里获得呢?
对于一个框架来说,别人要使用该框架,那么可以从最原始的官方压缩包中找到,但是其中的jar包有很多,我么可以从它提供的例子程序中找到,如Struts的官方原始压缩包,解压后如下图:
我们要从struts的官方开发包中获取我们需要的jar包,找到它提供给我们的例子,打开apps目录。如下图:
apps里面存放的都是struts官方提供的例子,都是war包,可以直接部署到tomcat中运行的例子程序,那么这里例子里面就有我们需要的jar包,我将其中一个解压出来。
struts2-blank-2.1.8.1目录中:
找到WEB-INF目录中的lib目录,将lib目录中的所有jar包都拷贝到我们项目中的lib目录中。
所以上面的这些jar包也可以这样获得。
上图中使用的是Struts 2.1.8版本,其他版本的都一样。
三大框架整合使用的时候,Struts的Action会交给Spring来管理,因此还需要一个Struts和和Spring整合的jar包:struts2-spring-plugin-2.1.6.jar
添加如下的jar包:
antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
hibernate3.jar
hibernate-jpa-2.0-api-1.0.1.Final.jar
javassist-3.12.0.GA.jar
jta-1.1.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
解压从官网下载下来的hibernate-distribution-3.6.0.Final.zip压缩包:
添加hibernate3.jar,lib\required\*.jar,lib\jpa\hibernate-jpa-2.0-api-1.0.0.Final.jar、(实体生成表时需要)、lib\optional\c3p0\c3p0-0.9.1.jar、mysql数据库的驱动包到web-inf/lib目录下。
需要用到数据库的操作,因此我们要用到数据库的驱动jar包,这里用的mysql数据库因此添加:mysql-connector-java-5.0.4-bin.jar
需要用到数据库连接池,这里使用c3p0数据库连接池,因此还需要添加c3p0的jar包:
c3p0-0.9.1.2.jar
这里使用的是Spring3.0的版本,添加Spring的jar包主要包括四个部分:
Spirng3-AOP 面向切面编程jar包
|--com.springsource.net.sf.cglib-2.2.0.jar
|--com.springsource.org.aopalliance-1.0.0.jar
|--com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
|--org.springframework.aop-3.0.1.RELEASE-A.jar
|--org.springframework.aspects-3.0.1.RELEASE-A.jar
|--org.springframework.instrument.tomcat-3.0.1.RELEASE-A.jar
|--org.springframework.instrument-3.0.1.RELEASE-A.jar
Spring3-Core 核心jar包
|--com.springsource.org.apache.commons.logging-1.1.1.jar
|--com.springsource.org.apache.log4j-1.2.15.jar
|--jmxtools-1.2.1.jar
|--org.springframework.asm-3.0.1.RELEASE-A.jar
|--org.springframework.beans-3.0.1.RELEASE-A.jar
|--org.springframework.context-3.0.1.RELEASE-A.jar
|--org.springframework.core-3.0.1.RELEASE-A.jar
|--org.springframework.expression-3.0.1.RELEASE-A.jar
Spring3-Persistence-Core 持久化jar包
|--org.springframework.jdbc-3.0.1.RELEASE-A.jar
|--org.springframework.orm-3.0.1.RELEASE-A.jar
|--org.springframework.transaction-3.0.1.RELEASE-A.jar
|--persistence.jar
Spring3-Web web支持的jar包
|--com.springsource.org.apache.commons.fileupload-1.2.0.jar
|--com.springsource.org.apache.commons.httpclient-3.1.0.jar
|--com.springsource.org.codehaus.jackson.mapper-1.0.0.jar
|--org.springframework.oxm-3.0.1.RELEASE-A.jar
|--org.springframework.web.portlet-3.0.1.RELEASE-A.jar
|--org.springframework.web.servlet-3.0.1.RELEASE-A.jar
|--org.springframework.web.struts-3.0.1.RELEASE-A.jar
|--org.springframework.web-3.0.1.RELEASE-A.jar
添加log4j的日志jar包
commons-lang3-3.1.jar
commons-logging-1.1.1.jar
log4j-1.2.11.jar
将以上三个框架列举的jar添加到项目的WEB-INF/lib目录下即可。
将项目中所有的配置文件都放置到一个Source Folder目录中,Source Folder目录等同于src目录,项目部署后会自动发布到classess目录中。
选择项目邮件 → New → Source Folder,新建一个Source Folder取名为config目录。
struts.xml的配置文件的写法基本上都是这样固定的,如下:
struts.xml文件的编写如下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 禁用动态方式访问 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<!-- 开发模式 -->
<constant name="struts.devMode" value="true" />
<!-- 简单主题 -->
<constant name="struts.ui.theme" value="simple" />
<!-- 拓展名为action -->
<constant name="struts.action.extension" value="action" />
<!-- struts package配置 -->
<package name="s2sh" namespace="/" extends="struts-default">
<!-- Action的配置在这里 -->
<action name="test_*" class="testAction" method="{1}">
</action>
</package>
</struts>
修改项目的web.xml配置文件,添加Struts的核心过滤器配置:
添加配置如下:
<!-- 配置Struts的核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Hibernate和Spring整合后可以将所有的配置信息都交给Spring配置,因此hibernate.cfg.xml不再需要。使用一个properties文件来配置数据库的连接信息,Spring则从该properties文件中获取数据库的连接信息,该配置文件为:jdbc.properties,编写如下:
##数据库连接地址
jdbcUrl=jdbc:mysql://localhost:3306/oa?useUnicode=true&characterEncoding=utf8
##数据库连接驱动
driverClass=com.mysql.jdbc.Driver
##用户名
user=root
##密码
password=root
##Hibernate使用的数据库方言
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
##Hibernate自动建表
hibernate.hbm2ddl.auto=update
##显示Sql语句
hibernate.show_sql=true
##格式化SQL语句
hibernate.format_sql=true
*.hbm.xml的配置文件我们将它同样的放置到config目录中,在该目录下建立一个hbm目录,将所有的*.hbm.xml文件都放置到该目录中便于Spring自动扫描所有的*.hbm.xml文件。Hbm文件的示例如下:User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="oa.user.model">
<class name="User" table="t_User">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
</class>
</hibernate-mapping>
appliactionContext.xml的配置文件编写如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 配置扫描注解自动装配bean -->
<context:component-scan base-package="s2sh"></context:component-scan>
<!-- 导入外部properties文件,配置数据库连接信息 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 配置SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- hibernate的配置信息 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
</props>
</property>
<!-- 配置扫描加载hbm映射文件的位置 -->
<property name="mappingDirectoryLocations">
<!-- list代表所有文件 -->
<list>
<!-- classpath路径下面的hbm文件夹中搜索hbm映射文件 -->
<value>classpath:hbm</value>
</list>
</property>
<!-- 配置c3p0数据库连接池 -->
<property name="dataSource">
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 配置数据库连接信息 -->
<property name="jdbcUrl" value="${jdbcUrl}" />
<property name="driverClass" value="${driverClass}" />
<property name="user" value="${user}" />
<property name="password" value="${password}" />
<!-- 其他配置 -->
<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="3" />
<!--连接池中保留的最小连接数。Default: 3 -->
<property name="minPoolSize" value="3" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="5" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="3" />
<!--
控制数据源内加载的PreparedStatements数量。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default:
0
-->
<property name="maxStatements" value="8" />
<!--
maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0
-->
<property name="maxStatementsPerConnection" value="5" />
<!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="1800" />
</bean>
</property>
</bean>
<!-- 配置事务管理(采用注解方式) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
项目中使用的日志管理,因此还添加一个做日志的配置文件:log4j.properties,其配置信息如下:
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change ‘info‘ to ‘debug‘ ###
log4j.rootLogger=error, stdout
#log4j.logger.org.hibernate=info
log4j.logger.officeoa=debug
### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug
### log just the SQL
#log4j.logger.org.hibernate.SQL=debug
### log JDBC bind parameters ###
#log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug
### log schema export/update ###
#log4j.logger.org.hibernate.tool.hbm2ddl=debug
### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug
### log cache activity ###
#log4j.logger.org.hibernate.cache=debug
### log transaction activity
#log4j.logger.org.hibernate.transaction=debug
### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug
### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
修改web.xml文件,添加Spring监听器:
<!-- 配置spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
最终的web.xml配置信息如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 配置spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<!-- 配置Struts的核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
最终config配置文件目录如下:
所有的测试类都放置在test目录中。
编写测试的Action类:
package test;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.opensymphony.xwork2.ActionSupport;
/**
* Action交给Spring管理
* @author Leo.Chen
*
*/
@Controller
@Scope("prototype")
public class TestAction extends ActionSupport {
@Override
public String execute() throws Exception {
return this.SUCCESS;
}
}
在struts.xml配置文件中添加Action的配置:
<!-- struts package配置 -->
<package name="s2sh" namespace="/" extends="struts-default">
<action name="testAction" class="testAction">
<result name="success">/test.jsp</result>
</action>
</package>
编写测试页面:test.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
Struts框架测试成功! <br>
</body>
</html>
部署访问:http://localhost:8080/s2sh/testAction.action
页面成功:
编写测试类:SpringHibernateTest.java
package test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试Spring与Hibernate环境搭建
*
* @author Leo.Chen
*
*/
public class SpringHibernateTest {
private ApplicationContext ac = new ClassPathXmlApplicationContext(
"applicationContext.xml");
/**
* 测试Spring
*/
@Test
public void testSpring() {
/**
* Struts的Action交给Spring的IOC容器管理,这里如果能获取testAction的实例对象,
* 说明Spring的IOC容器环境测试通过
*/
TestAction testAction = ac.getBean("testAction", TestAction.class);
System.out.println(testAction);
}
}
测试结果如下:
在SpringHibernateTest.java类中添加测试方法,测试Hibernate的持久化功能和Spring的事务管理功能。
/**
* 测试Hibernate功能和Spring的事务管理
*/
@Test
public void testHibernate_Tx() {
}
在测试之前需要做一些准备。
准备实体类和实体类对象的映射文件以及Service
User实体类:
package test;
public class User {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
与之对应的映射文件:User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test">
<class name="User" table="t_User">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
</class>
</hibernate-mapping>
编写Service测试添加用户功能,由于是测试环境因此就直接写Service的实现类了,而不写接口了。
package test;
import javax.annotation.Resource;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class TestService {
// 将sessionFactory注入
@Resource
private SessionFactory sessionFactory;
/**
* 添加用户
*/
public void save() {
Session session = sessionFactory.getCurrentSession();
session.save(new User());
int i = 1/0;// 这里报异常,事务管理会回滚
session.save(new User());
}
}
在SpringHibernateTest.java的testHibernate_Tx方法中加入测试代码:
/**
* 测试Hibernate功能和Spring的事务管理
*/
@Test
public void testHibernate_Tx() {
TestService testService = ac.getBean("testService", TestService.class);
testService.save();
}
分析测试结果:
把TestService类中的save()方法的异常代码注释掉,则能添加两个用户;如果加上该异常代码,则两个用户都不能添加。因此Spring的事务管理和Hibernate持久化功能测试通过。
test目录下的所有类:
修改TestAction中的代码,在Action中调用TestService的save方法,将TestService中的save方法中的异常代码注释掉。TestAction代码如下:
@Controller
@Scope("prototype")
public class TestAction extends ActionSupport {
@Resource
private TestService testService;
@Override
public String execute() throws Exception {
testService.save();
return this.SUCCESS;
}
}
重新部署访问:http://localhost:8080/s2sh/testAction.action
数据库中的数据结果:
建立包结构如下图:
暂时先建立上面的包结构,如果还需要用到其他的包,开发过程中再建立。
注意:在实际的开发中,业务逻辑比较少的情况下,可以将Dao和Service层合并为Service层,这里采用的就是这种策略。
针对基本的CRUD,我们需要将CRUD的所有公共代码都抽取到DaoSupport中。
在实际开发中我们需要面向接口开发,因此需要建立接口。在core下面的dao包中建立DaoSupport接口,将对应的实现类方法实现包impl中。如下:
DaoSupport接口的定义如下:
package s2sh.core.dao;
import java.util.List;
/**
* 通用Dao数据操作接口
* @author Leo.Chen
*
*/
public interface DaoSupport<T> {
/**
* 保存
* @param t
*/
public void save(T t);
/**
* 删除
* @param id
*/
public void delete(Long id);
/**
* 更新
* @param t
*/
public void update(T t);
/**
* 查询所有
* @return
*/
public List<T> findAll();
/**
* 根据Id查询
* @param id
* @return
*/
public T findById(Long id);
/**
* 根据一组id查询
* @param ids
* @return
*/
public List<T> findByIds(Long[] ids);
}
对应的实现类DaoSupportImpl
package s2sh.core.dao.impl;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
import s2sh.core.dao.DaoSupport;
/**
* 通用Dao数据操作实现类
*
* @author Leo.Chen
*
* @param <T>
*/
@SuppressWarnings("unchecked")
@Transactional
public abstract class DaoSupportImpl<T> implements DaoSupport<T> {
private Class<T> clazz;
@Resource
private SessionFactory sessionFactory;
public DaoSupportImpl() {
ParameterizedType pt = (ParameterizedType) this.getClass() .getGenericSuperclass();
clazz = (Class<T>) pt.getActualTypeArguments()[0];
}
public Session getSession() {
return sessionFactory.getCurrentSession();
}
@Override
public void save(T t) {
getSession().save(t);
}
@Override
public void delete(Long id) {
getSession().delete(getSession().get(clazz, id));
}
@Override
public void update(T t) {
getSession().update(t);
}
@Override
public List<T> findAll() {
return getSession().createQuery("FROM " + clazz.getSimpleName()).list();
}
@Override
public T findById(Long id) {
if (id != null) {
return (T) getSession().get(clazz, id);
} else {
return null;
}
}
@Override
public List<T> findByIds(Long[] ids) {
List<T> resultList = new ArrayList<T>();
if (ids != null) {
for (Long id : ids) {
resultList.add((T)this.getSession().get(clazz, id));
}
}
return resultList;
}
}
在基础环境中对Struts的Action做一个基础环境的抽取,使用ModelDriven拦截实现页面数据的封装,将所有的Service实例的声明都定义在BaseAction中,使得具体模块的Action只需要继承BaseAction即可,然后负责处理自己的业务逻辑即可。
BaseAction编写如下:
package s2sh.core.action;
import java.lang.reflect.ParameterizedType;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
/**
* 通用基础Action类
*
* @author Leo.Chen
*
* @param <T>
*/
@SuppressWarnings("unchecked")
public abstract class BaseAction<T> extends ActionSupport implements ModelDriven<T> {
private static final long serialVersionUID = 5412467040546639342L;
protected T model;
public BaseAction() {
ParameterizedType pt = (ParameterizedType) this.getClass() .getGenericSuperclass();
Class<T> clazz = (Class<T>) pt.getActualTypeArguments()[0];
try {
model = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
public T getModel() {
return model;
}
}
基本CRUD在Action中的六个方法:
/**
* 列表展示
*
* @return
* @throws Exception
*/
public String list() throws Exception {
return "list";
}
/**
* 删除
*
* @return
* @throws Exception
*/
public String delete() throws Exception {
return "toList";
}
/**
* 添加页面
*
* @return
* @throws Exception
*/
public String addUI() throws Exception {
return "saveUI";
}
/**
* 添加
*
* @return
* @throws Exception
*/
public String add() throws Exception {
return "toList";
}
/**
* 修改页面
*
* @return
* @throws Exception
*/
public String editUI() throws Exception {
return "saveUI";
}
/**
* 修改
*
* @return
* @throws Exception
*/
public String edit() throws Exception {
return "toList";
}
<!-- struts package配置 -->
<package name="s2sh" namespace="/" extends="struts-default">
<!-- 用户管理 -->
<action name="user_*" class="userAction" method="{1}">
<result name="list">/WEB-INF/jsp/user/list.jsp</result>
<result name="toList" type="redirectAction">user_list</result>
<result name="saveUI">/WEB-INF/jsp/user/save.jsp</result>
</action>
</package>
标签:struts2 spring hibernate 框架整合 s2sh框架整合
原文地址:http://blog.csdn.net/javachenzhenlin/article/details/42556655