导入依赖包:

除了导入Struts2和Spring的核心库之外,还要导入commons-logging和struts2-spring-plugin包。(PS:Struts2是主导,把spring嵌到struts2中。)

配置:

通过配置ContextLoaderListener监听器,使容器启动时,自动加载applicationContext配置,因为它实现了ServletContextListener这个接口,容器启动时会自动执行它实现的方法。

 

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  • 1.
  • 2.
  • 3.

默认情况下,会加载WEB-INF/applicationContext.xml这个文件,我们可以通过配置contextConfigLocation参数改变配置文件的路径。

 

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
  • 1.
  • 2.
  • 3.
  • 4.

以上配置均在web.xml文件的<web-app></web-app>区域。

Spring和Struts2的整合:

在web.xml中完成加载WebApplicationContext之后,接下来就可以做到Spring和Struts2的整合了。整合有两种方法,分别叙述如下:

第一种实现方法–把Action配置在beans.xml里,利用Spring初始化Action的bean:

1)  将Struts的业务逻辑控制器类(action)配置在Spring的配置文件中(由spring容器负责生成action),业务逻辑控制器中引用的业务类一并注入。注意,必须将业务逻辑控制器类配置为scope=”prototype”
示例如下:

<bean id=”LoginAction”=”yaso.struts.action.LoginAction”>
<property name=”loginDao”=”LoginDao”/>
</bean>
  • 1.
  • 2.
  • 3.

 

2)        在struts.xml或者等效的Struts2配置文件中配置Action时,指定<action>的class属性为Spring配置文件中相应bean的id或者name值

示例如下:

<action name=”LoginAction”=”LoginAction”>
<result name=”success”>/index.jsp</result>
</action>
  • 1.
  • 2.
  • 3.

第二种实现方法–不需要在beans.xml里配置Action,利用Struts-Spring_Plugin插件自动初始化Action:

1)        业务类在Spring配置文件中配置,业务逻辑控制器类(action)不需要配置,Struts2的Action像没有整合Spring之前一样配置,<action>的class属性指定业务逻辑控制器类的全限定名。

2)        业务逻辑控制器类中引用的业务类不需要自己去初始化,Struts2的Spring插件会使用bean的自动装配将业务类注入进来,其实业务逻辑控制器类也不是Struts2创建的,而是Struts2的Spring插件创建的。默认情况下,插件使用by name的方式装配,可以通过增加Struts2常量来修改匹配方式:设置方式为:struts.objectFactory.spring.autoWire = typeName,可选的装配参数如下:

  1. a) name:等价于Spring配置中的autowire=”byName”,这是缺省值。
  2. b) type:等价于Spring配置中的autowire=”byType”。
  3. c) auto:等价于Spring配置中的autowire=”autodetect”。
  4. d) constructor:等价于Spring配置中的autowire=” constructor”。

简述OpenSessionInViewFilter:

OpenSessionInViewFilter是Spring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开Hibernate的Session,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的。 由于Hibernate引入了Lazy Load特性,使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个LazyLoad的Exception。所以为了解决这个问题,Spring引入了这个Filter,使得Hibernate的Session的生命周期变长。

配置:

<!-- openSessionInView(请求结束后,才关闭session):注意配置的顺序,责任连,函数调用 -->
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

 

PS:因为是过滤器,一定要注意它的位置,要将它放在配置struts2的前面。

我的第一个SSH示例:

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"id="WebApp_ID"
version="3.1">
 
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<context-param>  
<param-name>contextConfigLocation</param-name>  
<param-value>classpath:beans.xml</param-value>  
</context-param>  
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
<!-- 默认加载:WEB-INF/applicationContext.xml -->
</listener>
<!-- openSessionInView(请求结束后,才关闭session):注意配置的顺序,责任连,函数调用 -->
<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInView</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>
  • 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.

 

beans.xml

 

<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
:xsi="http://www.w3.org/2001/XMLSchema-instance"
:context="http://www.springframework.org/schema/context"
:aop="http://www.springframework.org/schema/aop"
:tx="http://www.springframework.org/schema/tx"  
:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-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   
 >
<context:component-scan base-package="net.zmcheng"/>
<!-- 设置数据源:提供了一个标准化的取得数据库连接的方式,一看到property我们就应该有一个意识,那就是这个类当中有这个属性的setter方法来进行注入 -->
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">
<property name="driverClassName"value="com.mysql.jdbc.Driver"/>
<property name="url"value="jdbc:mysql://localhost:3306/BSWS?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username"value="root"/>
<property name="password"value="password"/>
</bean>
<!-- 整合Hibernate -->
<bean id="sessionFactory"class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource"ref="dataSource"/>
<!-- 使用注解的方式
           <property name="annotatedClasses">
               <list><value>net.zmcheng.model.NlUser</value></list>
           </property>
            -->
<property name="mappingResources">  
<list>  
<value>net/zmcheng/model/NlUser.hbm.xml</value>  
</list>     
</property>  
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- 声明式事务 -->  
<bean id="txManager"class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
<property name="sessionFactory"ref="sessionFactory"  
</bean>  
<!-- 采用@Transactional注解方式使用事务 
     <tx:annotation-driven transaction-manager="txManager"/>-->
<bean id=" logInterceptor"class="net.zmcheng.aop.LogInterceptor"/>
  
<aop:config>
<aop:pointcut expression="execution(public * net.zmcheng.serviceImpl..*.*(..))"id="servicePointCut"/>
<aop:advisor pointcut-ref="servicePointCut"advice-ref="txAdvice"/>
<aop:aspect id="logAspect"ref=" logInterceptor">
<aop:before method="before"pointcut-ref="servicePointCut"/>
<aop:around method="aroundMethod"pointcut-ref="servicePointCut"/>
</aop:aspect>
</aop:config>
<tx:advice id="txAdvice"transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*"read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
  
</beans>
  • 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.
  • 66.

struts2.xml

<?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>
<!-- 静态变量配置区域 -->
<!-- 执行动态编译 ,在开发完成之后要修改为false-->
<constant name="struts.devMode"value="true"></constant>
<!-- 支持ognl表达式访问静态方法 -->
<constant name="struts.ognl.allowStaticMethodAccess"value="true"></constant>
<!-- 配置视图编码方式为UTF-8-->
<constant name="struts-i18n.encoding"value="UTF-8"></constant>
 
<package name="zmc2"namespace="/user"extends="struts-default">
<action name="login"class="net.zmcheng.action.LoginRegisterAction">
<result>/demo.jsp</result>
</action>   
</package>
</struts>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

 

action:


 

Java

packagenet.zmcheng.action;
 
importcom.opensymphony.xwork2.ActionSupport;
 
importnet.zmcheng.service.UserService;
 
 
publicclassLoginRegisterActionextendsActionSupport{
 
privatestaticfinallongserialVersionUID=1L;
privateStringname;
privateStringpsw;
publicUserService getUserServiceImpl(){
returnuserServiceImpl;
}
publicvoidsetUserServiceImpl(UserService userServiceImpl){
this.userServiceImpl=userServiceImpl;
}
 
privateUserService  userServiceImpl;
 
publicStringexecute()throwsException{
userServiceImpl.add();
returnSUCCESS;
}
publicStringgetName(){
returnname;
}
 
publicvoidsetName(Stringname){
this.name=name;
}
 
publicStringgetPsw(){
returnpsw;
}
 
publicvoidsetPsw(Stringpsw){
this.psw=psw;
}
 
 
}
  • 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.

 

PS:DAO层,业务层之前博客有,在此不在缀余,业务层没写什么内容也就不粘了。