Struts2+Spring4+Hibernate5框架搭建(XML方式)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ITdevil/article/details/78393192

SSH框架如何整合?

SSH的框架整合,主要是分为两个部分。

其一:Spring整合Hibernate,总体来说就是将sessionFactory交给Spring容器来管理。(Spring整合AOP事务不做说明)

其二:Spring整合struts,就是Spring帮助struts2来管理action对象。

这里主要是想注重框架的搭建过程,让整个框架跑通。IDEEclipse,准备先采用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的默认事务原则是只读,我们 无法保存一个对象到数据库中,不能够做“写”的操作。


总结;前路漫漫,其修远兮!

本人菜鸟,只想着做个记录,方便自己以后回顾,如果文章对童鞋们有丝毫的小帮助,我也会感到快乐的!

如果觉得有什么地方错误,请各位及时指出,以免我误及他人!

最后,谢谢!(如果你能看到的话)




猜你喜欢

转载自blog.csdn.net/ITdevil/article/details/78393192