ssh-ssh整合(Struts2+Spring+Hibernate)

在之前呢我們已經講解過ssm以及ssm2的整合開發,今天我們進行ssh的整合,在之前已經有一篇整合ssh的文章,那是基於註解開發的,今天講解的爲基於配置文件注入方式進行開發。

思路:Spring管理hibernate相關會話工廠的創建以及負責管理hibernate的事務,同時spring容器管理service層的實現以及struts2的action,話不多說,我們進入正題。

同樣的,我們以一個用戶登錄的案例進行講解。

開發軟件:

Eclipse neon

Tomcat7.0

Jdk1.7

Struts2.3

Spring2.5

Hiberbate3.0


項目結構如下所示:


項目源碼下載:點擊下載

在線演示:點擊觀看

ssh的開發我們同樣的分爲標準的三層進行開發,首先我們進行Model層的開發。

Model

1、首先我們編寫po對象-User.java

package com.sw.domain;
/*
 *@Author swxctx
 *@time 2017年4月27日
 *@Explain:用戶表po對象
 *id:編號
 *username:用戶名
 *password:密碼
 */
public class User {
	private int id;
	private String username;
	private String password;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

2、編寫對應的hibernate映射文件-User.hbm.xml

<?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.sw.domain.User" table="user">
        <!-- 配置主鍵 -->
        <id name="id" type="int"> 
            <!-- 列定義 -->
            <column name="id" not-null="true" sql-type="int"></column>
            <!-- 生成策略 -->
            <generator class="uuid"></generator>
        </id>
        <!-- 字段配置 -->
        <property name="username" type="string">
            <column name="username" sql-type="varchar(50)"></column>
        </property>
        
        <property name="password" type="string">
            <column name="password" sql-type="varchar(50)"></column>
        </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://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">0707</property>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/bs</property>
		
		<!-- 事務自動提交,使用sessionFactory需要進行此項配置 -->
		<property name="hibernate.connection.autocommit">true</property>
		
		<!-- 配置方言 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
		<!-- 操作數據庫的形式 -->
		<property name="hibernate.hbm2ddl.auto">update</property>
		<!-- sql語句 -->
		<property name="hibernate.show_sql">true</property>
		
		
		<!-- 映射文件 -->
		<mapping resource="com/sw/domain/User.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

3、現在基本配置已經完成了,我們可以進行dao層的開發了,編寫UserDao.java文件

package com.sw.dao;

import com.sw.domain.User;

/*
 *@Author swxctx
 *@time 2017年5月10日
 *@Explain:Dao層接口
 */
public interface UserDao {
	public final static String SERVICE_NAME = "UserDaoImpl";
	
	//登錄
	public User findUserByUsername(String username);
	
}

4、接下來需要編寫實現類-UserDaoImpl.java

package com.sw.dao.impl;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.sw.dao.UserDao;
import com.sw.domain.User;

/*
 *@Author swxctx
 *@time 2017年5月10日
 *@Explain:Dao層實現
 */
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
	
	@Override
	public User findUserByUsername(String username) {
		Session session=null;
		User user=new User();
		try {
			session=this.getHibernateTemplate().getSessionFactory().openSession();
			Criteria criteria=(Criteria) session.createCriteria(User.class);
			//加入條件查詢
			criteria.add(Restrictions.eq("username", username));
			user=(User) criteria.uniqueResult();
		} finally {
			if(session!=null){
				session.close();
			}
		}
		return user;
	}

}

5、接下來我們需要通過Spring來管理SsqlsessionFactoty,同時需要通過spring管理dao層的方法,編寫applicatiobContext.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans  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"
		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.5.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 
	
    	<!-- 配置註解自動掃描範圍 -->
    	<context:component-scan base-package="com.sw"></context:component-scan>
    	
    	<!-- 創建SessionFactory工廠 -->
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    	    <property name="configLocation">
    	        <value>
    	            classpath:/hibernate/hibernate.cfg.xml
    	        </value>
    	    </property>
    	</bean>
    	
    	<!-- 配置dao層(注入sessionFactory) -->
    	<bean id="UserDaoImpl" class="com.sw.dao.impl.UserDaoImpl">
    		<!-- 注入sessionFactory -->
    		<property name="sessionFactory" ref="sessionFactory"></property>
    	</bean>
    	
</beans>

6、接下來我們需要編寫spring配置文件加載的工具類,在之前的ssm以及ssm2中已經講到,這裏不再重複。

加載配置文件類:

package com.sw.container;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
 *@Author swxctx
 *@time 2017年5月15日
 *@Explain:服務類,用用戶加載applicationContext.xml文件
 */
public class ServiceProvideCord {
	
	protected static ApplicationContext applicationContext;
	
	public static void load(String[] fileName){
		applicationContext = new ClassPathXmlApplicationContext(fileName);
	}
}

獲取bean服務的類:

package com.sw.container;

import org.apache.commons.lang.StringUtils;

/*
 *@Author swxctx
 *@time 2017年5月15日
 *@Explain:Service層服務類
 */
@SuppressWarnings("static-access")
public class SwServiceProvider {
	private static ServiceProvideCord serviceProvideCord;
	
	//靜態加載
	static{
		serviceProvideCord = new ServiceProvideCord();
		serviceProvideCord.load(new String[]{"classpath:/spring/applicationContext-service.xml",
				"classpath:/spring/applicationContext-dao.xml",
				"classpath:/spring/applicationContext-transaction.xml",
				"classpath:/spring/applicationContext-action.xml"});
	}
	
	public  static Object getService(String serviceName){
		//服務名稱爲空
		if(StringUtils.isBlank(serviceName)){
			throw new RuntimeException("當前服務名稱不存在...");
		}
		Object object = null;
		if(serviceProvideCord.applicationContext.containsBean(serviceName)){
			//獲取bean
			object = serviceProvideCord.applicationContext.getBean(serviceName);
		}
		if(object==null){
			throw new RuntimeException("服務名稱爲【"+serviceName+"】下的服務節點不存在...");
		}
		return object;
	}
}

7、如上,我們已經完成了編寫,可以進行測試了。

package com.sw.test;


import org.junit.Test;

import com.sw.container.SwServiceProvider;
import com.sw.dao.UserDao;
import com.sw.domain.User;

/*
 *@Author swxctx
 *@time 2017年5月18日
 *@Explain:hibernate(dao)測試
 */
public class DaoTest {
	

	@Test
	public void testFindUserByName() {
		UserDao userDao= (UserDao) SwServiceProvider.getService(UserDao.SERVICE_NAME);
		User user=(User) userDao.findUserByUsername("bs");
		if(user!=null){
			String string=user.getPassword();
			System.out.println(string);
		}else{
			System.out.println("");
		}
	}

}

測試結果如下:

如上所示,表明model層的開發已經無誤;記下來進行service層的開發。


Service

service層的開發主要包括Spring對hibernate的事務管理以及容器對service方法的管理。

1、編寫service層接口

package com.sw.service;


/*
 *@Author swxctx
 *@time 2017年5月10日
 *@Explain:Service層接口
 */
public interface UserService {
	public final static String SERVICE_NAME = "UserServiceImpl";
	
	//登錄查詢
	public String findUserByUsername(String username);
}

2、實現service層接口

package com.sw.service.impl;

import org.springframework.transaction.annotation.Transactional;

import com.sw.container.SwServiceProvider;
import com.sw.dao.UserDao;
import com.sw.domain.User;
import com.sw.service.UserService;

/*
 *@Author swxctx
 *@time 2017年5月10日
 *@Explain:Service層實現
 */

//指定事務提交級別
@Transactional(readOnly=true)
public class UserServiceImpl implements UserService{

	//驗證
	@Override
	public String findUserByUsername(String username) {
		UserDao userDao= (UserDao) SwServiceProvider.getService("UserDaoImpl");
		User user = userDao.findUserByUsername(username);
		String pass;
		if(user!=null){
			pass = user.getPassword();
		}else{
			pass = "";
		}
		return pass;
	}

}

3、接下來我們需要將service方法放到spring中管理,編寫applicationContext-service.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans  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"
		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.5.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 
	
    	<!-- 配置註解自動掃描範圍 -->
    	<context:component-scan base-package="com.sw"></context:component-scan>
    	
    	<!-- 配置Service層 -->
    	<bean id="UserServiceImpl" class="com.sw.service.impl.UserServiceImpl"></bean>
    	
</beans>

4、接着需要通過spring管理hibernate的事務,編寫配置文件applicationContext-transaction.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans  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"
		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.5.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 
	
    	<!-- 配置註解自動掃描範圍 -->
    	<context:component-scan base-package="com.sw"></context:component-scan>
    	
    	<!-- 創建事務管理器 -->
    	<bean id="swManage" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    	    <property name="sessionFactory" ref="sessionFactory"></property>
    	</bean>
    	
    	<!-- 以註解的形式管理事務 -->
    	<tx:annotation-driven transaction-manager="swManage"/>
    	
    	<!-- 通知 -->
		<tx:advice id="txAdvice" transaction-manager="swManage">
			<tx:attributes>
				<!-- 傳播行爲 -->
				<tx:method name="save*" propagation="REQUIRED"/>
				<tx:method name="delete*" propagation="REQUIRED"/>
				<tx:method name="insert*" propagation="REQUIRED"/>
				<tx:method name="update*" propagation="REQUIRED"/>
				<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
				<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
				<tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
			</tx:attributes>
		</tx:advice>
	
		<!-- aop -->
		<aop:config>
			<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.sw.service.impl.*.*(..))"/>
		</aop:config>
    	
</beans>

5、如上,service層的配置已經完成,加下來進行相關測試。

package com.sw.test;

import org.junit.Test;

import com.sw.container.SwServiceProvider;
import com.sw.service.UserService;

/*
 *@Author swxctx
 *@time 2017年5月18日
 *@Explain:Service測試
 */
public class ServiceTest {

	@Test
	public void testFindUserByUsername() {
		UserService userService=(UserService)SwServiceProvider.getService(UserService.SERVICE_NAME);
		String pass=userService.findUserByUsername("bs");
		System.out.println(pass);
	}

}

測試結果如下:

如圖,系統正常運行。


View

最後我們需要進行Struts2的開發,主要包括頁面的開發、action的開發以及將actioin放到spring中管理。

1、首先我們編寫界面文件login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<form action="login.action" mephod="post">
		用戶:<input type="text" id="username" name="username" placeholder="用戶名"><br>
		密碼:<input type="password" id="password" name="password" placeholder="密碼" ><br>
		<input type="submit" value="提交">
	</form>

</body>
</html>

successlogin.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>success</title>
</head>
<body>
	<p>登錄成功</p>
</body>
</html>

errlogin.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>err</title>
</head>
<body>
	<p>登錄失敗</p>
</body>
</html>

2、接下來需要編寫Vo對象,用於映射form表單提交的值,UserForm.java:

package com.sw.web.form;
/*
 *@Author swxctx
 *@time 2017年5月10日
 *@Explain:Vo對象-映射form表單
 */
public class UserForm {
	private int id;
	private String username;
	private String password;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

3、接下來需要編寫基礎action,繼承於request,BaseAction.java:

package com.sw.web.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;

import com.opensymphony.xwork2.ActionSupport;

/*
 *@Author swxctx
 *@time 2017年4月27日
 *@Explain:封裝Request與Response
 */
public class BaseAction extends ActionSupport implements ServletRequestAware,ServletResponseAware{

	private static final long serialVersionUID = 1L;
	
	protected HttpServletRequest request;
	protected HttpServletResponse response;
	
	@Override
	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

}

4、最後編寫處理登錄動作的action。LoginAction.java:

package com.sw.web.action;

import com.opensymphony.xwork2.ModelDriven;
import com.sw.container.SwServiceProvider;
import com.sw.service.UserService;
import com.sw.web.form.UserForm;

/*
 *@Author swxctx
 *@time 2017年4月27日
 *@Explain:登錄Action
 */
public class LoginAction extends BaseAction implements ModelDriven<UserForm>{
        //modeldriven-收集頁面數據
	private static final long serialVersionUID = 1L;
	/*創建vo對象*/
	UserForm userForm = new UserForm();
	
	/*加載applicationContext.xml*/
	private UserService userService = (UserService)SwServiceProvider.getService(UserService.SERVICE_NAME);
	

	@Override
	public UserForm getModel() {
		// TODO Auto-generated method stub
		return userForm;
	}
	
	/*處理*/
	@Override
	public String execute() throws Exception {
		/*調用service層LoginCheck函數校驗*/
		String pass= userService.findUserByUsername(userForm.getUsername());
		
		if(userForm.getPassword().equals(pass)){
			return "success";
		}else{
			return "error";
		}
	}
}
5、接下來需要將action放到spring中管理,編寫applicationContext-action.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans  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"
		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.5.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 
	
    	
    	<!-- struts2-Action配置 -->
    	<bean id="loginAction" class="com.sw.web.action.LoginAction" scope="prototype"></bean>
    
</beans>

6、在spring中配置以後,直接在struts.xml中引用即可,編寫struts.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
	"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
	
	<!-- 將action配置在spring容器中 -->
	<constant name="struts.objectFactory" value="spring"></constant> 
   	
   	<package name="ssh-template" extends="struts-default">
   	     <!-- 用戶登錄 -->
        <action name="login" class="loginAction">  
            <!-- 定義邏輯視圖和物理資源之間的映射 -->  
            <result name="success" type="redirect">
            	<param name="location">/login/successlogin.html</param>
            </result>  
            <result name="error" type="redirect">/login/errlogin.html</result>  
        </action> 
   	</package>
</struts>

7、最後一步,我們還需要對web.xml進行編寫,如下:

<?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_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>ssh-template</display-name>
  
  <!-- spring配置文件加載 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:/spring/applicationContext-*.xml</param-value>
  </context-param>
  <!-- 監聽器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!-- 配置struts2 -->
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
     <!-- 配置struts2配置文件的路徑 -->
     <init-param> 
        <param-name>config</param-name> 
        <param-value>struts-default.xml,struts-plugin.xml,/struts/struts.xml</param-value>
	 </init-param>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

至此,ssh的整合已經全部完成,我們可以打開服務器進行測試了,測試結果如下:

登錄界面:

登錄成功:

登錄失敗:


結語:

就我自己而言,比較喜歡使用配置文件的方式,雖然這樣開發速度比較慢,同時代碼也比較亂,但是我覺適合自己的開發方式可能速度也不一定會慢吧,掌握了配置文件的方式,再去掌握註解的方式。相信也會快很多吧,其實原理都是差不多的,都是從那個點出發,只不過中間的過程有些許不同, 但是最終完成的都是通過spring管理;ssh的開發,對比ssm、ssm2的開發,其實基本上沒有多大的差別,ssh的dao層也就是ssm以及ssm2的mapper,在之前ssm以及ssm2我們使用的是Mybatis的Mapper開發方式,所以也就僅僅這裏有一些差別,在其他地方其原理都是一樣,如果Mybatis使用傳統dao的開發方式,那麼起開發也就是一樣的。總之,個人覺得原理比較重要,學習了各個框架以後,再瞭解各個框架之間爲什麼要整合,那麼也就自然會整合了,以上純屬個人觀點,請多指教。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章