SSH 框架整合
SSH 框架整合的环境准备
SSH 三大框架需要的 jar包
Struts2 框架
struts-2.3.24\apps\struts2-blank\WEB-INF\lib\*.jar————Struts2 需要的所有 jar 包
struts2-spring-plugin-2.3.24.jar————Struts2 整合 Spring 的插件包
Hibernate 框架
hibernate-release-5.0.7.Final\lib\required\*.jar————Hibernate 框架需要的 jar 包
slf4j-api-1.6.1.jar————日志接口
slf4j-log4j12-1.7.2.jar————日志实现
mysql-connector-java-5.1.7-bin.jar————MySQL 的驱动包
Spring 框架
IoC 核心包(6个)
AOP 核心包(4个)
JDBC 模板和事务核心包(2个)
Spring 整合 JUnit 测试包
Spring 整合 Hibernate 核心包
Spring 整合 Struts2 核心包
SSH 三大框架需要的配置文件
Struts2 框架
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | <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>
 
 | 
- 在 src目录下创建struts.xml,用来配置Action
Hibernate 框架
- 在 src目录创建hibernate.cfg.xml配置文件
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | <hibernate-configuration><session-factory>
 
 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
 <property name="hibernate.connection.url">jdbc:mysql:///ssh01</property>
 <property name="hibernate.connection.username">root</property>
 <property name="hibernate.connection.password">541638</property>
 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
 
 
 <property name="hibernate.show_sql">true</property>
 <property name="hibernate.format_sql">true</property>
 <property name="hibernate.hbm2ddl.auto">update</property>
 
 
 <property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
 
 
 <mapping resource="com/renkaigis/domain/Customer.hbm.xml"/>
 </session-factory>
 </hibernate-configuration>
 
 | 
- 在 JavaBean所在的包下编写映射的配置文件:JavaBean类名.hbm.xml
Spring 框架
| 12
 3
 4
 5
 6
 7
 8
 
 | <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>classpath:applicationContext.xml</param-value>
 </context-param>
 
 | 
Spring 框架整合 Struts2 框架
表单访问 Action
- 导入 CRM项目的 UI 页面,找到添加客户的页面,修改 form 表单,访问 Action。
编写 CustomerAction 接收请求,在 struts.xml 中完成 Action 的配置
| 12
 3
 4
 5
 
 | <package name="crm" extends="struts-default" namespace="/">
 
 <action name="customer_*" class="com.renkaigis.web.action.CustomerAction" method="{1}"/>
 </package>
 
 | 
模型驱动封装数据
编写好客户的 JavaBean,在 Action 中使用模型驱动来封装数据。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | 
 
 public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {
 
 private Customer customer = new Customer();
 @Override
 public Customer getModel() {
 return customer;
 }
 
 
 
 
 
 
 public String add() {
 System.out.println("WEB 层:保存客户…");
 System.out.println(customer);
 return NONE;
 }
 }
 
 | 
在 Action 中获取到 service(开发不会使用,因为麻烦)
可以通过 WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext()); 来获取,但是这种方式编写代码太麻烦了!
Spring 整合 Struts2 框架的第一种方式(Action 由 Struts2 框架来创建)
- 因为导入的 struts2-spring-plugin-2.3.24.jar包自带一个配置文件 struts-plugin.xml ,该配置文件中有如下代码
| 1
 | <constant name="struts.objectFactory" value="spring" />
 | 
开启一个常量,如果该常量开启,那么下面的常量就可以使用
Spring 整合 Struts2 框架的第二种方式(Action 由 Spring 框架来创建)(强烈推荐)
Spring 框架整合 Hibernate 框架
Spring 框架整合 Hibernate 框架(有配置文件)
(带有 hibernate.cfg.xml 的配置文件。强调:不能加绑定当前线程的配置)
编写 CustomerDaoImpl 的代码,加入配置并且在 CustomerServiceImpl 中完成注入
CustomerDaoImpl.java:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | 
 
 public class CustomerDaoImpl implements CustomerDao {
 
 
 
 
 
 @Override
 public void save(Customer customer) {
 System.out.println("持久层:保存客户…");
 }
 }
 
 | 
CustomerServiceImpl.java:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | 
 
 public class CustomerServiceImpl implements CustomerService {
 private CustomerDao customerDao;
 public void setCustomerDao(CustomerDao customerDao) {
 this.customerDao = customerDao;
 }
 
 
 
 
 
 
 @Override
 public void save(Customer customer) {
 System.out.println("业务层:保存客户…");
 customerDao.save(customer);
 }
 }
 
 | 
实现步骤:Action 调用 Service ,Service 调用 Dao
编写映射的配置文件
Customer.hbm.xml:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | <hibernate-mapping><class name="com.renkaigis.domain.Customer" table="cst_customer">
 <id name="cust_id" column="cust_id">
 <generator class="native"/>
 </id>
 <property name="cust_name" column="cust_name"/>
 <property name="cust_user_id" column="cust_user_id"/>
 <property name="cust_create_id" column="cust_create_id"/>
 <property name="cust_source" column="cust_source"/>
 <property name="cust_industry" column="cust_industry"/>
 <property name="cust_level" column="cust_level"/>
 <property name="cust_linkman" column="cust_linkman"/>
 <property name="cust_phone" column="cust_phone"/>
 <property name="cust_mobile" column="cust_mobile"/>
 </class>
 </hibernate-mapping>
 
 | 
在 hibernate.cfg.xml 的配置文件中引入映射的配置文件
| 12
 
 | <mapping resource="com/renkaigis/domain/Customer.hbm.xml"/>
 
 | 
在 applicationContext.xml 中配置加载 hibernate.cfg.xml
| 12
 3
 4
 
 | <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
 <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
 </bean>
 
 | 
Dao 继承 HibernateDaoSupport 的工具类
在 CustomerDaoImpl 中想完成数据的添加,Spring 框架提供了一个 HibernateDaoSupport 的工具类,以后 DAO 都可以继承该类!
CustomerDaoImpl.java:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | 
 
 public class CustomerDaoImpl extends HibernateDaoSupport implements CustomerDao {
 
 
 
 
 
 @Override
 public void save(Customer customer) {
 System.out.println("持久层:保存客户…");
 
 this.getHibernateTemplate().save(customer);
 }
 }
 
 | 
applicationContext.xml:
| 12
 3
 4
 
 | <bean id="customerDao" class="com.renkaigis.dao.CustomerDaoImpl">
 <property name="sessionFactory" ref="sessionFactory"/>
 </bean>
 
 | 
开启事务的配置
- 先配置事务管理器,注意现在使用的是 Hibernate框架,所以需要使用Hibernate框架的事务管理器
| 12
 3
 4
 
 | <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
 <property name="sessionFactory" ref="sessionFactory"/>
 </bean>
 
 | 
| 12
 
 | <tx:annotation-driven transaction-manager="transactionManager"/>
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | 
 
 @Transactional
 public class CustomerServiceImpl implements CustomerService {
 private CustomerDao customerDao;
 public void setCustomerDao(CustomerDao customerDao) {
 this.customerDao = customerDao;
 }
 
 
 
 
 
 @Override
 public void save(Customer customer) {
 System.out.println("业务层:保存客户…");
 customerDao.save(customer);
 }
 }
 
 | 
Spring 框架整合 Hibernate 框架(无配置文件)
(不带有 hibernate.cfg.xml 的配置文件)
整合
要不带有 hibernate.cfg.xml 的配置文件,则需要将 hibernate.cfg.xml 中的配置移植到 applicationContext.xml 中。具体操作如下:
Hibernate 配置文件中的配置
- 数据库连接基本参数(4 大参数)
- Hibernate 相关的属性
- 连接池
- 映射文件
开始进行配置
| 12
 3
 4
 5
 6
 7
 
 | <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
 <property name="driverClass" value="com.mysql.jdbc.Driver"/>
 <property name="jdbcUrl" value="jdbc:mysql:///ssh01"/>
 <property name="user" value="root"/>
 <property name="password" value="541638"/>
 </bean>
 
 | 
applicationContext.xml:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
 
 <property name="dataSource" ref="dataSource"/>
 
 <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>
 <prop key="hibernate.hbm2ddl.auto">update</prop>
 </props>
 </property>
 
 <property name="mappingResources">
 <list>
 <value>com/renkaigis/domain/Customer.hbm.xml</value>
 </list>
 </property>
 </bean>
 
 | 
延迟加载问题
no session 异常
使用延迟加载的时候,在 WEB 层查询对象的时候程序会抛出异常!
解决方法
解决办法非常简单,Spring 框架提供了一个过滤器,让 session 对象在 WEB 层就创建,在 WEB 层销毁。只需要配置该过滤器即可。
- 但是:要注意需要在 struts2 的核心过滤器之前进行配置:
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | <filter>
 <filter-name>OpenSessionInViewFilter</filter-name>
 <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
 </filter>
 <filter-mapping>
 <filter-name>OpenSessionInViewFilter</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>
 
 | 
终极版 SSH 整合
配置文件
web.xml
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 
 | <?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
 version="4.0">
 
 
 <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>classpath:applicationContext.xml</param-value>
 </context-param>
 
 
 <filter>
 <filter-name>OpenSessionInViewFilter</filter-name>
 <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
 </filter>
 <filter-mapping>
 <filter-name>OpenSessionInViewFilter</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>
 
 
 <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>
 
 | 
struts.xml
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | <?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>
 <package name="crm" extends="struts-default" namespace="/">
 
 <action name="customer_*" class="customerAction" method="{1}"/>
 </package>
 </struts>
 
 | 
application.xml
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 
 | <?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: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.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx.xsd">
 
 
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
 <property name="driverClass" value="com.mysql.jdbc.Driver"/>
 <property name="jdbcUrl" value="jdbc:mysql:///ssh01"/>
 <property name="user" value="root"/>
 <property name="password" value="541638"/>
 </bean>
 
 
 <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
 
 <property name="dataSource" ref="dataSource"/>
 
 <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>
 <prop key="hibernate.hbm2ddl.auto">update</prop>
 </props>
 </property>
 
 <property name="mappingResources">
 <list>
 <value>com/renkaigis/domain/Customer.hbm.xml</value>
 </list>
 </property>
 </bean>
 
 
 <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
 <property name="sessionFactory" ref="sessionFactory"/>
 </bean>
 
 
 <tx:annotation-driven transaction-manager="transactionManager"/>
 
 
 
 <bean id="customerAction" class="com.renkaigis.web.action.CustomerAction" scope="prototype">
 <property name="customerService" ref="customerService"/>
 </bean>
 <bean id="customerService" class="com.renkaigis.service.CustomerServiceImpl">
 <property name="customerDao" ref="customerDao"/>
 </bean>
 
 <bean id="customerDao" class="com.renkaigis.dao.CustomerDaoImpl">
 <property name="sessionFactory" ref="sessionFactory"/>
 </bean>
 </beans>
 
 | 
log4j.properties
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | ### direct log messages to stdout ###log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 log4j.appender.stdout.Target=System.err
 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
 
 ### direct messages to file mylog.log ###
 log4j.appender.file=org.apache.log4j.FileAppender
 log4j.appender.file.File=c\:mylog.log
 log4j.appender.file.layout=org.apache.log4j.PatternLayout
 log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
 
 ### set log levels - for more verbose logging change 'info' to 'debug' ###
 
 log4j.rootLogger=info, stdout
 
 | 
WEB 项目
控制层
CustomerAction.java ,继承 ActionSupport 类,使用 模型驱动 封装数据(记得手动 new,手动实例化 JavaBean)。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 
 | package com.renkaigis.web.action;
 import com.opensymphony.xwork2.ActionSupport;
 import com.opensymphony.xwork2.ModelDriven;
 import com.renkaigis.domain.Customer;
 import com.renkaigis.service.CustomerService;
 
 
 
 
 public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {
 
 private Customer customer = new Customer();
 
 @Override
 public Customer getModel() {
 return customer;
 }
 
 
 private CustomerService customerService;
 public void setCustomerService(CustomerService customerService) {
 this.customerService = customerService;
 }
 
 
 
 
 
 
 public String add() {
 System.out.println("WEB 层:保存客户…");
 customerService.save(customer);
 return NONE;
 }
 }
 
 
 | 
业务层
CustomerServiceImpl.java,添加事务注解,处理业务逻辑,调用持久层。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 
 | package com.renkaigis.service;
 import com.renkaigis.dao.CustomerDao;
 import com.renkaigis.domain.Customer;
 import org.springframework.transaction.annotation.Transactional;
 
 
 
 
 @Transactional
 public class CustomerServiceImpl implements CustomerService {
 private CustomerDao customerDao;
 public void setCustomerDao(CustomerDao customerDao) {
 this.customerDao = customerDao;
 }
 
 
 
 
 
 
 @Override
 public void save(Customer customer) {
 System.out.println("业务层:保存客户…");
 customerDao.save(customer);
 }
 
 @Override
 public void update(Customer customer) {
 customerDao.update(customer);
 }
 }
 
 | 
持久层
CustomerDaoImpl.java,继承 HibernateDaoSupport 类,使用 Hibernate 模板类实现 Java 类与数据库之间的转换和访问。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | package com.renkaigis.dao;
 import com.renkaigis.domain.Customer;
 import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
 
 
 
 
 public class CustomerDaoImpl extends HibernateDaoSupport implements CustomerDao {
 
 
 
 
 @Override
 public void save(Customer customer) {
 System.out.println("持久层:保存客户…");
 
 this.getHibernateTemplate().save(customer);
 }
 
 @Override
 public void update(Customer customer) {
 this.getHibernateTemplate().update(customer);
 }
 }
 
 
 |