SSH框架如何整合?
SSH的框架整合,主要是分为两个部分。
其一:Spring整合Hibernate,总体来说就是将sessionFactory交给Spring容器来管理。(Spring整合AOP事务不做说明)
其二:Spring整合struts,就是Spring帮助struts2来管理action对象。
这里主要是想注重框架的搭建过程,让整个框架跑通。
IDE
是
Eclipse
,准备先采用
xml
的方式完成环境的搭建,这种纯xml的方式尽管不是很流行了,但是有些东西还是必须要会使用的。至于主流的使用当然是
xml+注解
的方式,有机会会补上的。这里算是记录下自己搭建框架的过程吧,方便自己以后的使用,因为记忆力是有限的,该记录的还是要记录。开始,开始。。。。。。。
第一步:创建web工程
第二步:导包
我将所有需要用到的jar包资源已经上传。
jar资源链接:
SSH框架搭建jar包
使用方法:解压完成以后,只需要将所有jar包copy到WEB-INF下的lib中即可。部分截图如下:
ps:
总共导入了
40
个包,如果后期需要添加功能,按照自己的需求添加jar包即可
第三步:准备数据库
这里使用
mysql
数据库,创建一个名为
build_ssh
的数据库,并添加了一张表以及几条测试数据,建表语句及插入的数据如下:
CREATE TABLE user_test(
user_id INT PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR(20),
user_password VARCHAR(20)
);
INSERT INTO user_test VALUES(1,'jack','123');
INSERT INTO user_test VALUES(2,'rose','123');
第四步:搭建Spring环境,并整合web项目
1)创建application.xml,导入约束,Spring环境搭建成功!
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
</beans>
2)配置WEB-INF下的web.xml
在搭建struts2的环境之前,根据struts2的运行原理,一定要首先想到配置struts2的入口过滤器,这点我经常就忘记,所以顺带就配置了struts2的入口过滤器。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>build_ssh</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- Spring启动监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 确定Spring配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 配置struts2的入口过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!-- <init-param>
<param-name>struts.enable.DynamicMethodInvocation</param-name>
<param-value>true</param-value>
</init-param> -->
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
第五步:Spring整合Hibernate
使用Spring整合hibernate的思路是:首先创建一个实体类,编写映射文件和hibernate的配置文件,把原先在hibernate中的基本配置(连接JDBC的步骤)交给Spring来管理,并且在Spring中(applicationContext.xml)配置session工厂,让Spring容器来管理session工厂。完成上述步骤以后,编写测试类,测试Spring是否与Hibernate整合成功。
1)创建实体类
package com.ssh.domain;
public class User {
private int userId;
private String userName;
private String userPassword;
public int getUserId() {
return userId;
}
public String getUserName() {
return userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserId(int userId) {
this.userId = userId;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName + ", userPassword=" + userPassword + "]";
}
}
2)创建实体类的映射文件User.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ssh.domain">
<class name="User" table="user_test">
<id name="userId" column="user_id">
<generator class="identity"></generator> <!-- 这里主键生成策略换成native也是可以的 -->
</id>
<property name="userName" column="user_name"></property>
<property name="userPassword" column="user_password"></property>
</class>
</hibernate-mapping>
3)创建hibernate的配置文件hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 会话工厂 -->
<session-factory>
<!-- 数据库方言,根据数据库选择 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!--为了方便调试是否在运行hibernate时在日志中输出sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 是否对日志中输出的sql语句进行格式化 -->
<property name="hibernate.format_sql">true</property>
<!--是否自动建表,这里关掉了,我们自己前面已经建好了-->
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- 加载映射文件 -->
<mapping resource="com/ssh/domain/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
4)配置applicationContext.xm,让Spring来管理session工厂,并且把原来hibernate中关于数据库连接的部分也一并交给Spring容器来管理。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<!-- 开启IOC支持,包扫描 -->
<!-- 扫描该包下的所有类,用于IOC,由spring帮我们生成对象,因为测试的时候会用到注解所以这里先将开关打开 -->
<context:component-scan base-package="com.ssh"></context:component-scan>
<!-- 配置数据源 -->
<!-- 原先在hibernate.cfg.xml中配置的连接,现在交给Spring来管理 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/build_ssh"></property>
<property name="user" value="root"></property><!--修改成自己的用户名和密码-->
<property name="password" value="root"></property>
</bean>
<!-- 配置sessionFactory,由Spring来管理session工厂 -->
<bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- hibernate的基础配置和可选配置 -->
<property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
</bean>
</beans>
5)编写测试类,验证Spring是否整合hibernate成功
package com.ssh.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.ssh.domain.User;
@RunWith(SpringJUnit4ClassRunner.class) //spring整合了junit测试
@ContextConfiguration("classpath:applicationContext.xml") //用于加载spring的配置文件,初始化容器
public class HIbernateTest {
@Autowired
private SessionFactory factory; //spring容器为我们提供了工厂对象,这里使用注解的方式去容器中拿到该对象
@Test
public void fun2(){
Session session = factory.openSession(); //从session工厂中拿到session对象
Transaction tx = session.beginTransaction(); //开启事务
// 要执行的操作是保存一个用户
User u = new User();
u.setUserName("evil");
u.setUserPassword("123");
session.save(u); //将user对象持久化到数据库中
tx.commit(); //提交事务
session.close(); //关闭session
}
}
6)结果验证:在方法上右击junit test,出现下面结果,对象被持久化到了数据库中,恭喜你整合第一步成功!
Hibernate:
insert
into
user_test
(user_name, user_password)
values
(?, ?)
数据‘tom’已插入… |
截至目前,项目的结构如图所示:(寻思着也该截一个图了,至于其它的包,因为下面使用到,所以我先提前建好了)
第六步:Spring整合Struts2
spring整合struts2的思路:我们想通过浏览器输入地址,请求到struts2的一个action,然后跳转至结果页面。所以我们首先应该创建一个userAction,然后再struts2中配置好该action,但是该action对象我们要交给spring容器来帮我们生成(以前是struts帮我们生成),所以还需要在spring的配置文件中,配置好该action对象。
1)编写测试用的UserAction
package com.ssh.web;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
public String save(){
System.out.println("Spring整合struts2成功!");
return SUCCESS;
}
}
2)配置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.devMode" value="true"></constant>
<!-- 启用spring工厂,整合Spring的总开关 -->
<constant name="struts.objectFactory" value="spring"></constant>
<package name="struts" namespace="/" extends="struts-default">
<action name="UserAction_*" class="userAction" method="{1}"><!--注意这里的class="userAction",不是类的全路径了,是从Spring容器中获取的action-->
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
3)配置applicationContext.xml,让Spring来帮我们生成UserAction对象
在配置文件下方加入以下代码即可:
<!-- 配置action对象 -->
<bean name="userAction" class="com.ssh.web.UserAction" scope="prototype"><!-- 千万不要忽略scope这个属性,因为action对象是多例的 -->
<!-- <property name="userService" ref="userService"></property> -->
</bean>
4)在WebContext下创建index.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
Spring整合struts2成功了!
</body>
</html>
5)在tomcat上部署项目,运行,浏览器上输入地址:http://localhost:8080/build_ssh/UserAction_save 。如果跳转至index.jsp页面看到提示信息,则证明Spring整合struts2成功!
至此,三大框架的整合完成了三分之二了,还有重要的一点,就是spring整合AOP事务
第七步:Spring整合AOP事务
spring整合AOP事务的思路:我们采用注册的案例来体现Spring整合AOP事务,前台在注册页面填写好表单以后,提交表单到action中,action中通过对象驱动的方式接受前台传递过来的用户名和密码,从web层进入到service层,然后继而到dao层中。原本我们想要通过hibernate持久化一个对象到数据库中,必须先要获得session,打开事务,调用session.save()方法持久化对象,提交事务,对象此时就会持久化到了数据库中。现在由spring为我们做这些关于事务的操作(开启事务,提交事务,回滚事务),我们只注重于业务逻辑—-即保存用户。那Spring具体是怎么整合事务的?以上只是简单的描述,具体步骤不在这里详细说明,有空总结一发。下面开始采用注册案例来体现我们的spring对事务的管理。
项目的结构如图:
1)dao层编写
package com.ssh.dao;
import com.ssh.domain.User;
public interface UserDao {
void saveUser(User user);
}
实现类
package com.ssh.dao.impl;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import com.ssh.dao.UserDao;
import com.ssh.domain.User;
//导包时要注意,不要将hibernate5的包导成了hibernate4或3
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
/*
* 为什么要继承HibernateDaoSupport?
* 答:因为dao层本来是依赖于HibernateTemplate的,该模板中封装了一些事务的操作,需要我们在Spring的配置文件中配置HIbernateTemplate.
* 我们继承自HibernateDaoSupport,就使得dao层直接依赖于sessionFactory
* 当然这里也可以写HibernateTeplate,方法很多种,自己用着舒服就行
*/
@Override
public void saveUser(User user) {
this.getHibernateTemplate().save(user);
}
}
2)service层编写
package com.ssh.service;
import com.ssh.domain.User;
public interface UserService {
void saveUser(User user);
}
实现类
package com.ssh.service.impl;
import com.ssh.dao.UserDao;
import com.ssh.domain.User;
import com.ssh.service.UserService;
public class UserServiceImpl implements UserService {
//service层依赖于dao,我们想要获得dao层对象,不用自己创建了,直接去容器中拿就可以,
//但是前提是需要在容器中配置好dao层的东西。
//而且这里需要提供get和set方法,以便于我们在容器中使用属性注入的方式给service层注入dao的依赖
private UserDao userDao;
@Override
public void saveUser(User user) {
userDao.saveUser(user);
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
3)web层的编写(还是使用原来的action,修改了其中的方法,并添加了一个service的属性和一个对象驱动)
package com.ssh.web;
import com.opensymphony.xwork2.ActionSupport;
import com.ssh.domain.User;
import com.ssh.service.UserService;
public class UserAction extends ActionSupport {
//采用对象驱动的方式接收前台传过来的值
private User user =new User();
private UserService userService;
public String save() {
userService.saveUser(user);
return SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
}
4)在Spring中配置事务
<!-- 配置事务管理器 -->
<bean name="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" read-only="false"/>
<tx:method name="update*" read-only="false"/>
<tx:method name="delete*" read-only="false"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<aop:pointcut expression="execution(* com.ssh.service.*.*(..))" id="txPC"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPC"/>
</aop:config>
5)配置各层的bean对象
<!-- 配置dao -->
<bean name="userDao" class="com.ssh.dao.impl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置service -->
<bean name="userService" class="com.ssh.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<!-- 配置action对象 -->
<bean name="userAction" class="com.ssh.web.UserAction" scope="prototype"><!-- 千万不要忽略scope这个属性,因为action对象是多例的 -->
<property name="userService" ref="userService"></property>
</bean>
至此,完整的applicationContext.xml配置完成,以下就是完整的配置文件,莫要觉得乱糟糟!
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
<!-- 开启IOC支持,包扫描 -->
<!-- 扫描该包下的所有类,用于IOC,由spring帮我们生成对象,因为测试的时候会用到注解所以这里先将开关打开 -->
<context:component-scan base-package="com.ssh"></context:component-scan>
<!-- 配置数据源 -->
<!-- 原先在hibernate.cfg.xml中配置的连接,现在交给Spring来管理 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/build_ssh"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!-- 配置sessionFactory,由Spring来管理session工厂 -->
<bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- hibernate的基础配置和可选配置 -->
<property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
</bean>
<!-- 配置事务管理器 -->
<bean name="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" read-only="false"/>
<tx:method name="update*" read-only="false"/>
<tx:method name="delete*" read-only="false"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<aop:pointcut expression="execution(* com.ssh.service.*.*(..))" id="txPC"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPC"/>
</aop:config>
<!-- 配置dao -->
<bean name="userDao" class="com.ssh.dao.impl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置service -->
<bean name="userService" class="com.ssh.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<!-- 配置action对象 -->
<bean name="userAction" class="com.ssh.web.UserAction" scope="prototype"><!-- 千万不要忽略scope这个属性,因为action对象是多例的 -->
<property name="userService" ref="userService"></property>
</bean>
</beans>
7)编写前台页面register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册页面</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/UserAction_save" method="post">
用户名:<input name="user.userName" type="text"/><br>
密码:<input name="user.userPassword" type="password"/><br>
<input type="submit" value="注册"/>
</form>
</body>
</html>
8)测试注册:浏览器输入地址访问register.jsp页面
输入用户名和密码,点击注册,会跳转到成功页面!
到此,Spring整合AOP完成,如果不加AOP事务配置的话或事务配置错误的话,会抛出如下异常信息:
因为没有配置事务之前,Spring整合hibernate的默认事务原则是只读,我们 无法保存一个对象到数据库中,不能够做“写”的操作。
总结;前路漫漫,其修远兮!
本人菜鸟,只想着做个记录,方便自己以后回顾,如果文章对童鞋们有丝毫的小帮助,我也会感到快乐的!
如果觉得有什么地方错误,请各位及时指出,以免我误及他人!
最后,谢谢!(如果你能看到的话)