Struts2+Spring4+Hibernate5框架搭建(XML方式)
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環境搭建成功!
2)配置WEB-INF下的web.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 "> </beans>
在搭建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的預設事務原則是隻讀,我們 無法儲存一個物件到資料庫中,不能夠做“寫”的操作。
總結;前路漫漫,其修遠兮!
本人菜鳥,只想著做個記錄,方便自己以後回顧,如果文章對童鞋們有絲毫的小幫助,我也會感到快樂的!
如果覺得有什麼地方錯誤,請各位及時指出,以免我誤及他人!
最後,謝謝!(如果你能看到的話)