一、本节说明
本节主要记录SSH整合的时候需要的相关配置,配置的时候有点蒙,特此记录一下。
二、配置信息
1.所需jar包
首先是struts所需的jar包(9个):
- strus解压目录/lib下(8个)jar包,是哪些jar包请参考:
Struts2项目实战 微云盘(二):项目结构 - 以及struts2-spring-plugin-2.1.8.1.jar,该包也在lib下,它是Spring整合struts所需的jar包
其次是hibernate所需的jar包(14个):
- hibernate解压目录/lib/required下所有jar包(10个)
- hibernate解压目录/lib/optional/c3p0下所有jar包,该包是c3p0是数据源相关的包(3个)
- 数据库驱动文件(1个)
最后是spring所需的jar包(24个):
- spring解压目录/libs下的所有以RELEASE.jar为后缀名的jar包(21个)
- aspectj解压目录下/lib下的三个jar包;
- aopalliance.jar
- aspectjrt.jar
- aspectjweaver.jar
- -
共47个jar包
2.目录结构
以下主要展示配置文件所在位置
SpringDemo1
|_src
|_struts.xml
|_WebRoot
|_WEB-INF
|_lib
|_applicationContext.xml
|_web.xml
3.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<!-- 定义sruts2的核心Filter -->
<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>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!-- web容器启动时会自动装配applicationContext.xml -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
3.struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- 允许动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
<constant name="struts.il8n.encoding" value="UTF-8" />
<package name="lzf" namespace="/" extends="struts-default">
<!-- 登录Action -->
<action name="loginAction" class="cn.lzf.shopping.action.LoginAction">
<result name="error">/WEB-INF/content/login_err.jsp</result>
<result>/WEB-INF/content/login_succ.jsp</result>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
<result name="login">/WEB-INF/content/login.jsp</result>
</action>
</package>
</struts>
3.application.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:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
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.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<aop:aspectj-autoproxy proxy-target-class="true" />
<!-- 配置数据源 -->
<bean
id="dataSourse"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="com.mysql.jdbc.Driver"
p:jdbcUrl="jdbc:mysql://localhost/hibernate"
p:user="root"
p:password="123456"
p:maxPoolSize="40"
p:minPoolSize="2"
p:initialPoolSize="2"
p:maxIdleTime="30" />
<!-- 配置SessionFactory -->
<bean
id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSourse">
<property name="annotatedClasses">
<list>
<!-- 罗列持久化类 -->
<value>cn.lzf.shopping.orm.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect
</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- 配置局部事务管理器 -->
<bean
id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<!-- 配置事务增强处理 Bean -->
<tx:advice
id="txAdvice"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method
name="get*"
read-only="true" />
<tx:method
name="*"
isolation="DEFAULT"
propagation="REQUIRED"
timeout="5" />
</tx:attributes>
</tx:advice>
<!-- AOP配置的元素 -->
<!--该expression表达式指定为哪些类的哪些方法添加增强处理-->
<aop:config>
<aop:pointcut
expression="bean(userService)"
id="myPointcut" />
<aop:advisor
advice-ref="txAdvice"
pointcut-ref="myPointcut" />
</aop:config>
<!-- 分隔符分隔符分隔符分隔符分隔符分隔符 -->
<!-- 定义用户业务逻辑组件,并注入DAO组件 -->
<!-- 在LoginAction将自动装配该bean -->
<bean
id="userService"
class="cn.lzf.shopping.service.UserServiceImpl"
p:userDao-ref="userDao" />
<!-- 定义用户DAO组件,并注入sessionFactory -->
<bean
id="userDao"
class="cn.lzf.shopping.dao.UserDaoHibernate"
p:sessionFactory-ref="sessionFactory"></bean>
<!-- 定义User Bean -->
<bean
id="user"
class="cn.lzf.shopping.orm.User"></bean>
</beans>
三、注意事项
至此,基本配置已经完成,在Spring整合Struts时有两种方式:
- Spring容器作真正的控制器,Struts作伪控制器,当用户请求被Struts拦截后Struts自己不创建Bean实例,而是由Spring创建Bean。
在Struts中配置Action时不配置它的具体实现类,而是配置该Bean在Spring中的id值。
在struts.xml中进行如下配置,class属性值并不是实现类,而是id
<!-- 登录Action -->
<action name="loginAction" class="realLoginAction">
<result name="error">/WEB-INF/content/login_err.jsp</result>
<result>/WEB-INF/content/login_succ.jsp</result>
</action>
在applicationContext.xml中进行如下配置,依赖注入由Spring完成:
<bean
id="realLoginAction"
class="cn.lzf.shopping.action.LoginAction"
scope="prototype"
p:userService-ref="userService"
p:user-ref="user">
</bean>
- 使用自动装配
在struts.xml中配置Action与不使用Spring时一模一样
<!-- 登录Action -->
<action name="loginAction" class="cn.lzf.shopping.action.LoginAction">
<result name="error">/WEB-INF/content/login_err.jsp</result>
<result>/WEB-INF/content/login_succ.jsp</result>
</action>
使用自动装配时Spring不需要再单独配置该bean,那么Spring怎么知道为其注入哪些bean呢?
所以这就要求该Action所依赖的Bean的名字与在Spring中配置的名字相同。
如下,LoginAction有如下片段
public class LoginAction extends ActionSupport{
//用户业务逻辑组件
private UserService userService;
private User user;
//...
}
所以在applicationContext.xml中必须要以下片段,注意bean的id与Action中依赖的对象名是相同的。
<!-- 定义User Bean -->
<bean
id="user"
class="cn.lzf.shopping.orm.User"></bean>
<!-- 定义用户业务逻辑组件,并注入DAO组件 -->
<!-- 在LoginAction将自动装配该bean -->
<bean
id="userService"
class="cn.lzf.shopping.service.UserServiceImpl"
p:userDao-ref="userDao" />
四、OGNL使用注意事项
当使用OGNL将请求参数转换为Bean对象时,稍不注意就会有问题,在jsp中使用:
注意textfield的name属性值
<s:form action="loginAction" id="form1">
<s:textfield label="用户名" name="user.tel"></s:textfield>
<s:textfield label="密码" name="user.password"></s:textfield>
<s:submit value="登录账号" id="submit"></s:submit>
</s:form>
表单的数据会被提交到loginAction,那么在loginAction的实现类中肯定有属性名为user的Bean对象,该属性必须有setter、getter方法
这里用到了User对象的tel、name,所以在User类中必须为这两个参数设置setter、getter方法。