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 框架
1 2 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
配置文件
1 2 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 框架
1 2 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 的配置
1 2 3 4 5
| <package name="crm" extends="struts-default" namespace="/"> <action name="customer_*" class="com.renkaigis.web.action.CustomerAction" method="{1}"/> </package>
|
模型驱动封装数据
编写好客户的 JavaBean,在 Action 中使用模型驱动来封装数据。
1 2 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
:
1 2 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
:
1 2 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
:
1 2 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
的配置文件中引入映射的配置文件
1 2
| <mapping resource="com/renkaigis/domain/Customer.hbm.xml"/>
|
在 applicationContext.xml
中配置加载 hibernate.cfg.xml
1 2 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
:
1 2 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
:
1 2 3 4
| <bean id="customerDao" class="com.renkaigis.dao.CustomerDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> </bean>
|
开启事务的配置
- 先配置事务管理器,注意现在使用的是
Hibernate
框架,所以需要使用 Hibernate
框架的事务管理器
1 2 3 4
| <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean>
|
1 2
| <tx:annotation-driven transaction-manager="transactionManager"/>
|
1 2 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 相关的属性
- 连接池
- 映射文件
开始进行配置
1 2 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
:
1 2 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 的
核心过滤器之前
进行配置:
1 2 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
1 2 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
1 2 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
1 2 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
1 2 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
)。
1 2 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
,添加事务注解,处理业务逻辑,调用持久层。
1 2 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 类与数据库之间的转换和访问。
1 2 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); } }
|