SSH整合例項詳解
專案構建
新建web專案ssh2,建好後新增struts功能
新增spring功能:(注意選擇的spring版本,並且取消掉MyEclipse自帶的jar包,我們之後手動加入相應的jar包)
完成之後新增hibernate功能:
這裡的資料庫驅動連線加不加都是可以的,因為後面我們要有一個dbconfig.properties檔案手動配置資料庫驅動。
完成之後,我們手動加入struts2+spring+hibernate需要的jar包:
spring整合hibernate和struts,只要在配好了applicationContext.xml,在struts的action中直接呼叫就可以了。hibernate訪問資料庫的操作都在spring中實現了,spring的呼叫又在stuts的action中實現了。所以我們刪掉了無用的hibernate配置檔案hibernate.cfg.xml。
之後就可以在相應的層裡實現需要的功能了。以下實現一個簡單的註冊使用者功能:
完成之後我們的專案檔案就是下面這樣的:
實現程式碼
User.java
package com.lmb.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable{
private static final long serialVersionUID = 1L;
private Long id;
private String loginname;
private String password;
private Integer age;
private Date birthday;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this .loginname = loginname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((age == null) ? 0 : age.hashCode());
result = prime * result
+ ((birthday == null) ? 0 : birthday.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result
+ ((loginname == null) ? 0 : loginname.hashCode());
result = prime * result
+ ((password == null) ? 0 : password.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (age == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (birthday == null) {
if (other.birthday != null)
return false;
} else if (!birthday.equals(other.birthday))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (loginname == null) {
if (other.loginname != null)
return false;
} else if (!loginname.equals(other.loginname))
return false;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
return true;
}
}
User實體類配置檔案:
User.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/HibernateMapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<!-- xml檔案配置Hibernate實體對映 -->
<hibernate-mapping package="com.lmb.hibernate.domain"><!--實體類所在的包 -->
<!-- 實體類 -->
<class name="User" table="user"><!-- name=""用來指定實體類, table=""用來指定資料庫表格 -->
<id name="id" column="id" type="java.lang.Long"><!-- id主鍵 -->
<generator class="native"/><!--資料庫自動增長 -->
</id>
<property name="loginname" type="java.lang.String"></property><!-- 配置實體類變數-->
<property name="password" type="java.lang.String"></property><!-- 配置實體類變數-->
<property name="age" type="java.lang.Integer"></property><!-- 配置實體類變數-->
<property name="birthday" type="java.util.Date"></property><!-- 配置實體類變數-->
</class>
</hibernate-mapping>
UserManagerImpl.java
package com.lmb.manager;
import com.lmb.dao.UserDao;
import com.lmb.domain.User;
public class UserManagerImpl implements UserManager{
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void saveUser(User user) {
userDao.insertObject(user);
}
}
UserAction.java
package com.lmb.web.action;
import com.lmb.domain.User;
import com.lmb.manager.UserManager;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport{
private User user;
private UserManager userManager;
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute(){
userManager.saveUser(user);
return SUCCESS;
}
}
application-user.xml把有關User的操作的配置從applicationContext.xml分離出來,單獨配置;
application-user.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="userDao" class="com.lmb.dao.UserDaoImpl" parent="baseDao"></bean>
<bean id="userManager" class="com.lmb.manager.UserManagerImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userAction" class="com.lmb.web.action.UserAction" scope="prototype">
<property name="userManager" ref="userManager"></property>
</bean>
</beans>
本例中的applicationContext.xml實現了以下作用:
1、配置資料來源;
2、配置SessionFactory;
3、配置事務管理;
4、匯入分離出的配置檔案application-user.xml;
applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- 讀取屬性檔案 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:dbconfig.properties"></property>
</bean>
<!-- 配置資料來源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="${URL}"></property>
<property name="driverClassName" value="${DRIVER_CLASS}"></property>
<property name="username" value="${USER_NAME}"></property>
<property name="password" value="${PASSWORD}"></property>
</bean>
<!-- 配置SessionFactoryBean -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 注入資料來源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 載入對映配置檔案 -->
<property name="mappingResources">
<list>
<value>com/lmb/domain/User.hbm.xml</value>
</list>
</property>
<!-- -如果使用的是@註解的形式,對映的實體類應該以下面這種形式載入->
<property name="annotatedClasses">
<list>
<value>實體類全路徑</value>
</list>
</property>
<!-- 關於hibernate屬性的配置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<bean id="baseDao" class="com.lmb.dao.BaseDaoImpl" abstract="true">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<import resource="application-user.xml" />
</beans>
資料庫驅動屬性檔案:
dbconfig.properties
struts.xml中配置控制層的action,因為SSH整合之後struts是由spring來管理的,所以這裡的class屬性只需要給出spring配置檔案中相應action具體實現的id即可;
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="ssh" extends="struts-default" >
<action name="userAction" class="userAction">
<result>/ok.jsp</result>
</action>
</package>
</struts>
在web.xml中配置struts的分發器和spring的上下文物件applicationcontext的構建監聽器,所有的請求都被對映到struts2上,專案啟動時構建applicationcontext物件,並儲存到servletContext物件中,在執行時就可以使用spring的上下文物件,這個物件永遠不會消失。
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">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 該監聽器的作用:專案啟動時構建applicationcontext物件,並儲存到servletContext物件中,在執行時就可以使用spring的上下文物件,這個物件永遠不會消失 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 通過該節點告訴servletContext物件到哪裡去讀取applicationcontext的配置檔案,如果配置檔案讀取失敗applicationcontext物件就會構建失敗 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<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></web-app>
index.jsp
<form action="userAction.action">
使用者名稱:<input type="text" name="user.loginname" /><br/>
密碼:<input type="password" name="user.password"/><br/>
年齡:<input type="text" name="user.age"/><br/>
出生日期:<input type="text" name="user.birth"/><br/>
<input type="submit" value="submit"/><br/>
</form>
有關幾個配置檔案的總結:
1、web.xml
web.xml中要配置struts的分發器,所有的請求都被對映到struts2上。還要配置一個spring的監聽器用於構建spring的上下文物件applicationcontext,以便專案啟動時構建就applicationcontext物件,並儲存到servletContext物件中,在執行時就可以使用spring的上下文物件;
2、struts.xml
struts.xml中只需要配置控制層action的相關資訊,要注意因為SSH整合之後spring整合hibernate和struts,所以struts的配置檔案struts.xml要依賴於spring的配置檔案applicationContext.xml.
以上配置也充分體現了struts的功能: struts 負責 web 層 .ActionFormBean 接收網頁中表單提交的資料,然後通過 Action 進行處理,再 Forward 到對應的網頁。在 struts.xml 中定義 <action>
, 相應的Action就 會載入。
3、applicationContext.xml
spring配置檔案applicationContext.xml的作用:
1)、配置資料來源;
2)、配置SessionFactory;
3)、配置事務管理;
4)、配置資料持久層;xxxDao
5)、配置業務邏輯層; xxxService(xxxManager)
6)、配置控制層; xxxAction
7)、配置POJO;xxx
在實際的業務應用中,實體會有很多,如果都配置在applicationContext.xml中,管理起來非常麻煩,所以,我們可以把有關實體的配置抽取出來,單獨寫到一個檔案中去application-xxx.xml,該配置檔案實現的功能就是:
4)、配置資料持久層;xxxDao
5)、配置業務邏輯層; xxxService(xxxManager)
6)、配置控制層; xxxAction
7)、配置POJO;xxx
而applicationContext.xml只需要將抽取出的配置檔案引入並實現以下功能:
1)、配置資料來源;
2)、配置SessionFactory;
3)、配置事務管理;
以上配置也充分體現了spring的功能:
spring 負責業務層管理,即 Service (或 Manager).
1) . service (或 Manager)為 action 提供統一的呼叫介面,封裝持久層的 DAO.
2 ).可以寫一些自己的業務方法。
3 ).統一的 javabean 管理方法
4 ).宣告式事務管理:整合 Hiberante
4、xxx.hbm.xml
配置Hibernate實體對映 ,該實體對映也可以用@註解的形式配置。
Hibernate的配置檔案hibernate.cfg.xml的作用是配置資料庫驅動,並宣告用XML檔案或者@註解配置的實體類,但SSH整合之後spring整合hibernate和struts,有關資料庫驅動和宣告用XML檔案或者@註解配置的實體類的配置被放到applicationContext.xml下的SessionFactoryBean配置中,所以該配置檔案不需要再用到。