SSH配置

本人ssh框架的版本是:struts2.2.3,hibernate3.1.2,spring3.0.6

下载地址:

Struts:http://struts.apache.org/download.cgi

hibernate:http://www.hibernate.org/downloads
spring:http://www.springsource.org/download

框架搭建:

1.jsp+struts+spring+hibernate

2.ext+struts2/servlet+spring+hibernate
   ext+dwr+spring+hibernate

(当然我们可以同时使用struts和dwr,但是要注意冲突的解决,同理struts和servlet的冲突也是这样解决的,见附录1)
3.flex+blazeds+spring+hibernate
   flex+webservices+spring+ibatis(见附录5)
Struts2配置:

必备jar:

struts2-core-2.1.6.jar

freemarker-2.3.13.jar

commons-logging-1.0.4.jar

ognl-2.6.11.jar

xwork-2.1.2.jar

补充:

commons-fileupload-1.2.1.jar,struts2.0.14并不需要此包,只有在要用到上传组件的时候才需要。可能是struts2.1.6对文件上传功能的改进。因此要想正常使用struts2.1.6,至少需要如下6 个jar包:

struts2-core-2.1.6.jar

freemarker-2.3.13.jar

commons-logging-1.0.4.jar

ognl-2.6.11.jar

xwork-2.1.2.jar

commons-fileupload-1.2.1.jar

struts.xml是通过从struts-2.2.3-all.zip 解压后的 \struts-2.2.3\apps 目录中的案例的\WEB-INF\classes 的目录中得到。把struts.xml文件拷贝到项目的src目录进行修改。

web.xml的修改也是通过参考已有项目中的\WEB-INF\web.xml文件 

struts2 ok!!!

 

Spring配置:

dist:该文件夹下放Spring的jar包,通常只需要Spring.jar文件即可。该文件夹下还有一些类似spring-Xxx.jar的压缩包, 这些压缩包是spring.jar压缩包的子模块压缩包。除非确定整个J2EE应用只需要使用Spring的某一方面时,才考虑使用这中分模块压缩包。通常建议使用Spring.jar

 

Spring.jar是包含有完整发布的单个jar包,Spring.jar中包含除了 Spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到Spring-mock.jar来进行辅助测试,正式应用系统中是用不得这些类的。

除了Spring.jar文件,Spring还包括有其它13个独立的jar包,各自包含着对应的Spring组件,用户可以根据自己的需要来选择组合自己的jar包,而不必引入整个Spring.jar的所有类文件。

1.Spring-core.jar
这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。

2.Spring-beans.jar
这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI支持,引入Spring-core.jar及Spring- beans.jar文件就可以了。

3.Spring-aop.jar
这个jar文件包含在应用中使用Spring的AOP特性时所需的类。使用基于AOP的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。

4.Spring-context.jar
这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI所需的全部类,UI方面的用来与模板(Templating)引擎如 Velocity、FreeMarker、JasperReports集成的类,以及校验Validation方面的相关类。

5.Spring-dao.jar
这个jar文件包含Spring DAO、Spring Transaction进行数据访问的所有类。为了使用声明型事务支持,还需在自己的应用里包含Spring-aop.jar。

6.Spring-hibernate.jar
这个jar文件包含Spring对Hibernate 2及Hibernate 3进行封装的所有类。

7.Spring-jdbc.jar
这个jar文件包含对Spring对JDBC数据访问进行封装的所有类。

8.Spring-orm.jar
这个jar文件包含Spring对DAO特性集进行了扩展,使其支持 iBATIS、JDO、OJB、TopLink,因为Hibernate已经独立成包了,现在不包含在这个包里了。这个jar文件里大部分的类都要依赖 Spring-dao.jar里的类,用这个包时你需要同时包含Spring-dao.jar包。

9.Spring-remoting.jar
这个jar文件包含支持EJB、JMS、远程调用Remoting(RMI、Hessian、Burlap、Http Invoker、JAX-RPC)方面的类。

10.Spring-support.jar
这个jar文件包含支持缓存Cache(ehcache)、JCA、JMX、邮件服务(Java Mail、COS Mail)、任务计划Scheduling(Timer、Quartz)方面的类。

11.Spring-web.jar
这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。

12.Spring-webmvc.jar
这个jar文件包含Spring MVC框架相关的所有类。包含国际化、标签、Theme、视图展现的FreeMarker、JasperReports、Tiles、Velocity、 XSLT相关类。当然,如果你的应用使用了独立的MVC框架,则无需这个JAR文件里的任何类。

13.Spring-mock.jar
这个jar文件包含Spring一整套mock类来辅助应用的测试。Spring测试套件使用了其中大量mock类,这样测试就更加简单。模拟HttpServletRequest和HttpServletResponse类在Web应用单元测试是很方便的。

如何选择这些发布包,决定选用哪些发布包其实相当简单。如果你正在构建Web应用并将全程使用Spring,那么最好就使用单个全部的Spring.jar文件;如果你的应用仅仅用到简单的Inversion of Control / Dependency Injection(IoC/DI)容器,那么只需Spring-core.jar与Spring-beans.jar即可;如果你对发布的大小要求很高,那么就得精挑细选了,只取包含自己所需特性的jar文件了。采用独立的发布包你可以避免包含自己的应用不需要的全部类。当然你可以采用其它的一些工具来设法令整个应用包变小,节省空间的重点在于准确地找出自己所需的Spring依赖类,然后合并所需的类与包就可以了。Eclispe有个插件叫 ClassPath Helper可以帮你找找所依赖的类。

Spring包依赖说明:
1) Spring-core.jar需commons-collections.jar,Spring-core.jar是以下其它各个的基本。
2) Spring-beans.jar需Spring-core.jar,cglib-nodep-2.1_3.jar
3) Spring-aop.jar需Spring-core.jar,Spring-beans.jar,cglib-nodep-2.1_3.jar,aopalliance.jar
4) Spring-context.jar需Spring-core.jar,Spring-beans.jar,Spring-aop.jar,commons-collections.jar,aopalliance.jar
5) Spring-dao.jar需Spring-core.jar,Spring-beans.jar,Spring-aop.jar,Spring-context.jar
6) Spring-jdbc.jar需Spring-core.jar,Spring-beans.jar,Spring-dao.jar
7) Spring-web.jar需Spring-core.jar,Spring-beans.jar,Spring-context.jar
8) Spring-webmvc.jar需Spring-core.jar/Spring-beans.jar/Spring-context.jar/Spring-web.jar
9) Spring -hibernate.jar需Spring-core.jar,Spring-beans.jar,Spring-aop.jar,Spring- dao.jar,Spring-jdbc.jar,Spring-orm.jar,Spring-web.jar,Spring-webmvc.jar
10) Spring-orm.jar需Spring-core.jar,Spring-beans.jar,Spring-aop.jar,Spring- dao.jar,Spring-jdbc.jar,Spring-web.jar,Spring-webmvc.jar
11) Spring -remoting.jar需Spring-core.jar,Spring-beans.jar,Spring-aop.jar,Spring- dao.jar,Spring-context.jar,Spring-web.jar,Spring-webmvc.jar
12) Spring-support.jar需Spring-core.jar,Spring-beans.jar,Spring-aop.jar,Spring-dao.jar,Spring-context.jar,Spring-jdbc.jar
13) Spring-mock.jar需Spring-core.jar,Spring-beans.jar,Spring-dao.jar,Spring-context.jar,Spring-jdbc.jar

1.spring 结合flex

Spring的MVC框架是一个请求驱动的Web框架,其设计围绕一个中心的Servlet进行,它能将请求分发给控制器,并提供其他功能帮助Web应用开发。

DispatcherServlet实际上是一个Servlet,它从HttpServlet继承而来。和其他Servlet一样,DispatcherServlet定义在Web应用的web.xml文件里。DispatcherServlet处理的请求必须在同一个web.xml文件里使用url-mapping定义映射,下面的例子演示了如何配置DispatcherServlet:

 

  1. <web-app>
  2. <servlet>
  3.      <servlet-name>Dispatcher</servlet-name>
  4.      <servlet-class>
  5.          org.springframework.web.servlet.DispatcherServlet
  6.      </servlet-class>
  7.      <init-param>
  8.          <param-name>contextConfigLocation</param-name>
  9.          <param-value>/WEB-INF/applicationContext.xml</param-value>
  10.      </init-param>
  11.      <load-on-startup>1</load-on-startup>
  12. </servlet>
  13. <servlet-mapping>
  14.      <servlet-name>Dispatcher</servlet-name>
  15.      <url-pattern>*.do</url-pattern>
  16. </servlet-mapping>
  17. </web-app>

 

 

 

在上面的配置中,所有以.do结尾的请求都会由名为Dispatcher的DispatcherServlet处理,该Servlet配置了初始化参数contextConfigLocation,设置IoC配置文件的名称为/WEB-INF/application- Context.xml。如果不配置该参数,则它会读取默认的文件名/WEB-INF/Dispatcher-servlet.xml。通常习惯使用applicationContext.xml,也可以配置多个XML文件:

 

  1. <init-param>
  2.      <param-name>contextConfigLocation</param-name>
  3.      <param-value>/WEB-INF/applicationContext.xml,
  4.      /WEB-INF/part2.xml</param-value>
  5. </init-param>

 

 

 

在基于Struts+Spring的联合应用中,接收请求的Servlet是由Struts的ActionServlet来配置的,因此此时就不能够使用DispatcherServlet来接收请求了。为了在此时能够加载Spring的Bean配置,可以在web.xml中配置一个监听器,并通过<context-param>指定XML文件名,如下所示:

 

  1. <context-param>
  2.      <param-name>contextConfigLocation</param-name>
  3.      <param-value>/WEB-INF/applicationContext.xml</param-value>
  4. </context-param>
  5. <listener>
  6.      <listener-class>
  7.          org.springframework.web.context.ContextLoaderListener
  8.      </listener-class>
  9. </listener>

 

 

 

2.spring 关于DispatcherServlet功能详解

项目中需要同时用到两个视图解析器,一个报表的,一个jsp的。这就产生了标题所述的需求。通过阅读Spring Framework参考手册以及示例,解决了这个问题,中间也走了不少弯路,碰到了不少问题,特记录下来。

配置多个DispatcherServlet有多种方法,一种是在DispatcherServlet中直接指定此DispatcherServlet对应的配置文件。例如:

<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/app-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>

但是这种配置方法存在一个问题:由于DispatcherServlet对应的Controller需要访问Service并且使用dataSource,而DispatcherServlet之间的上下文是分离的,势必会出现多个dataSource的情况,降低了数据库连接使用的效率。

后来找到了第二种方法,目前正在使用的:DispatcherServlet不指定具体的配置文件,并且DispatcherServlet只初始化自己需要使用到的Controller类,然后由org.springframework.web.context.ContextLoaderListener初始化除Controller以外的全部对象。这样子多个dataSource的问题解决了。配置如下:

web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/*-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>

由于没有指定名称,所以spring默认会在WEB-INF目录下寻找DispatcherServlet名称开头的-servlet.xml文件,上面这个配置寻找的app-servlet.xml文件。

app-servlet.xml:
<!– 扫描所有的业务Controller,加载json转换服务对象,排除所有的报表Controller –>
<context:component-scan base-package=”com.xieshaohu.**.action” >
<context:include-filter type=”regex” expression=”.*JacksonConversionServiceConfigurer$”/>                 <context:exclude-filter type=”aspectj” expression=”com.xiehshaohu.project.reports.action.**.*”/> </context:component-scan>

<!– 通过 @Controller 注解实例化Controller类 –>
<mvc:annotation-driven />
<!– JSP视图控制器 –>
<bean id=”jspViewResolver”>
<property name=”viewClass” value=”org.springframework.web.servlet.view.JstlView”/>
<property name=”prefix” value=”/WEB-INF/views/” />
<property name=”suffix” value=”.jsp” />
</bean>

另外还有一个report-servlet.xml配置,web.xml中的内容和app的配置类似。

report-servlet.xml:
<!– 扫描所有的报表Controller对象 –>
<context:component-scan base-package=”com.xieshaohu.project.reports.action” />
<!– Configures the @Controller programming model –>
<mvc:annotation-driven />
<bean id=”viewResolver” class=”org.springframework.web.servlet.view.ResourceBundleViewResolver”>   <property name=”basename” value=”views” />
</bean>

然后就是在org.springframework.web.context.ContextLoaderListener初始化的-config.xml配置文件中实例化Service和Dao了。

<!– 扫描Classpath下所有的@Compnents对象,排除Controller和json转换服务对象 –>
<context:component-scan base-package=”com.xieshaohu”>
<context:exclude-filter type=”regex” expression=”.*Controller$”/>
<context:exclude-filter type=”regex” expression=”.*JacksonConversionServiceConfigurer$”/> </context:component-scan>

通过以上配置,现在就可以实现多个DispatcherServlet了,并且共享了同一个dataSource。在配置的过程中碰到了以下问题。

  1. @Transactional不生效,导致连接泄露。
    按照约定,所有的@Transactional注解都是在@Service中,出现这个问题的原因是,我在app-servlet.xml中初始化了所有的对象,包括@Controller,@Service,@Repository。但是按照官方手册314页正上方的说明,DispatherServlet扫描的对象中使用了@Transactional注解,则只会扫描@Controller中的@Transctional注解。所以出现了连接泄露的问题。所以最后配置成了只在*-servlet.xml中初始化@Controller。
    英文原文:
    <tx:annotation-driven/> only looks for @Transactional on beans in the same application context it is defined in. This means that, if you put <tx:annotation-driven/> in a WebApplicationContext for a DispatcherServlet, it only checks for @Transactional beans in your controllers, and not your services.
  2. DispatcherServlet间互相访问的问题。
    这个问题直接参考Application Context – three ways to get the context的第一种方法解决。实现ApplicationContextAware接口即可。
  3. Service没有使用接口编程,导致@Controller初始化时提示找不到对应的Service实例。
    上面这个问题通过修改程序解决,看来面向接口编程很重要,下面这点更加充分的说明了问题。
  4. Service实例化时提示无法访问通过@Repository注解声明的Dao
    出现这个问题的原因还是因为没有在Service中使用接口引用Dao,导致程序在初始化时就要寻找实例。

 

hibernate配置:

Hibernate3.0 采用新的基于ANTLR的HQL/SQL查询翻译器,需要用到antlr

hibernate3.jar:   Hibernate的库,没有什么可说的,必须使用的jar包

cglib-2.1.3.jar:  CGLIB库,Hibernate用它来实现PO字节码的动态生成,非常核心的库,必须使用的jar包

asm.jar:          和cglib-2.1.3.jar有点类似

dom4j.jar:        dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,dom4j无论在那个方面都是非常出色的。我早在将近两年之前就开始使用dom4j,直到现在。如今你可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这是必须使用的jar包,Hibernate用它来读写配置文件。

commons-collections.jar: Apache Commons包中的一个,包含了一些Apache开发的集合类,功能比java.util.*强大。必须使用的jar包。

commons-logging.jar: 它的出现是一个历史的的遗留的遗憾,当初Apache极力游说Sun把log4j加入JDK1.4,然而JDK1.4项目小组已经接近发布JDK1.4产品的时间了,因此拒绝了Apache的要求,使用自己的java.util.logging,这个包的功能比log4j差的很远,性能也一般。后来Apache就开发出来了commons-logging.jar用来兼容两个logger。因此用commons-logging.jar写的log程序,底层的Logger是可以切换的,你可以选择log4j,java.util.logging或者它自带的Simple Logger。不过我仍然强烈建议使用log4j,因为log4j性能很高,log输出信息时间几乎等于System.out,而处理一条log平均只需要5us。你可以在Hibernate的src目录下找到Hibernate已经为你准备好了的log4j的配置文件,你只需要到Apache 网站去下载log4j就可以了。commons-logging.jar也是必须的jar包。

log4j-1.2.11.jar: 不用多说了

jta.jar: JTA规范,JTA(Java Transaction API)是一种高层的,与实现无关的,与协议无关的API,应用程序和应用服务器可以使用JTA来访问事务。当Hibernate使用JTA的时候需要,不过App Server都会带上,所以也是多余的。我这里必须使用,可能是因为Tomcat只是Web Server而非App Server的缘故。

ehcache-1.1.jar: 在Hibernate中使用它作为数据缓存的解决方案.

antlr-2.7.6rc1.jar: 在用hibernate3.0进行查询,

附录1:

 <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>

struts2.2.3的过滤器,过滤的所有的请求,造成找不到dwr框架。

StrutsConstants。STRUTS_ACTION_EXCLUDE_PATTERN常量来保存不由struts处理的请求路径,因此我们可以在struts2.properties中配置即可。

struts.action.excludePattern=/dwr/.*,/dwr/test/.*即可。

附录2:

关于web.xml中配置SSH框架

<?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">
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath*:applicationContext-*.xml</param-value>
 </context-param>

<!--

在web.xml中通过contextConfigLocation配置,springcontextConfigLocation参数定义了要装入的 Spring 配置文件。

在配置文件中,配置SessionFactory,事务,aop切面,beans实例化。。。

<bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="configLocation">
   <value>classpath:hibernate.cfg.xml</value>
  </property>
 </bean>
 
 <bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
 </bean>
   <tx:advice id="txAdvice" transaction-manager="transactionManager" >
  <tx:attributes>
   <tx:method name="find*" propagation="REQUIRED" />
   <tx:method name="get*" propagation="REQUIRED" />
   <tx:method name="show*" propagation="REQUIRED" />
   <tx:method name="Show*" propagation="REQUIRED" />
   <tx:method name="Add*" propagation="REQUIRED" />
   <tx:method name="load*" propagation="REQUIRED" />
   <tx:method name="update*" propagation="REQUIRED" />
   <tx:method name="del*" propagation="REQUIRED" />
   <tx:method name="add*" propagation="REQUIRED" />
   <tx:method name="Sys*" propagation="REQUIRED" />
   <tx:method name="*" read-only="false" />
  </tx:attributes>
 </tx:advice>
 <aop:config>
 <!--
 execution(返回值  包名.类名.方法(..))
 实现到具体的类
 pointcut="execution(* com.rjxy.petro.dao.impl.UserDaoImpl.*(..))" />
   上面:<tx:advice id="txAdvice",下面:advice-ref="txAdvice" 共同txAdvice
  -->
  <!-- 规则 -->
  <aop:advisor pointcut="execution(* com.rjxy.petro.dao.impl.*.*(..))" advice-ref="txAdvice"/>
  <!-- aop可以大范围,也可以具体到类 -->
  <aop:advisor pointcut="execution(* com.rjxy.petro.dao.impl.*.*(..))" advice-ref="logManageAdvice" />
  <aop:advisor pointcut="execution(* com.rjxy.petro.dao.impl.*.*(..))" advice-ref="AdviceBeforeComponent"/>
  <aop:advisor pointcut="execution(* com.rjxy.petro.dao.impl.*.*(..))" advice-ref="AfterComponentAdvice"/>
  <aop:advisor pointcut="execution(* com.rjxy.petro.dao.impl.*.*(..))" advice-ref="AroundComponentAdvice"/>
 </aop:config>

但是一般是在业务层进行事务的管理而不是在数据链接层:

 <!-- 配置事务的传播特性 -->
 <tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
   <tx:method name="add*" propagation="REQUIRED"/>
   <tx:method name="del*" propagation="REQUIRED"/>
   <tx:method name="modify*" propagation="REQUIRED"/>
   <tx:method name="*" read-only="true"/>
  </tx:attributes>
 </tx:advice>
 
 <!-- 那些类的哪些方法参与事务 -->
 <aop:config>
  <aop:pointcut id="allManagerMethod" expression="execution(* com.bjsxt.service.*.*(..))"/>
  <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/>
 </aop:config>

在web.xml里配置Listener

 

xml 代码如下: 

 

  <listener>  

 

        < listener-class >  org.springframework.web.context.ContextLoaderListener  listener-class  >   

 

   </listener>    

 

如果在web.xml里给该Listener指定要加载的xml,如:

xml代码如下:

<!-- spring config -->

      <context-param>

           <param-name>contextConfigLocation</param-name>  

           <param-value>classpath:applicationContext.xml</param-value>

      </context-param>

则会去加载相应的xml,而不会去加载/WEB-INF/下的applicationContext.xml。

但是,如果没有指定的话,默认会去/WEB-INF/下加载applicationContext.xml。

<tx:method/> 有关的设置

Readonly事务的特性是
事务资源不做任何事情,这样在一个有事务context的thread中,Readonly事务可以大大的优化事务,不需要去执行和监视 transaction对象的 Prepare(),commit(),abort()的回调函数。 更深层次的考虑是
1:在XA下,所有Read-Only的事务将直接转变为 1 阶段事务。
2:整个事务不会去Lock事务资源。事务资源可以自由释放,并且被其他thread引用。(这个是并发控制中,事务资源优化的主要手段)

spring的事务有只读与可写之分: 两者的根本区别就是只读事务所做的数据库修改不会提交到数据库.
需要注意2点:
1.HibernateTemplate的如下API检查了当前事务是否只读,如果是只读会抛出InvalidDataAccessApiUsageException异常:
save,update,saveOrUpdate,saveOrUpdateAll,replicate,persist,merge,delete,deleteAll
但是HibernateTemplate并未保证只读事务进行数据库写操作肯定抛出此异常,在只读事务中使用以上API之外的方法做数据库写操作就不会抛出异常,也不会提交到数据库.
2.如果只读事务中嵌套了另一个事务,且内嵌事务的级别设置为PROPAGATION_REQUIRED,则内嵌事务同样是只读的,不会真正提交,即便内层事务为非只读事务.

-->
  <listener>
  <listener-class>
   org.springframework.web.context.ContextLoaderListener
  </listener-class>
 </listener>

<!--

ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息,配置信息存放在contextConfigLocation所指定的配置文件中。

-->
 <filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>
   org.springframework.web.filter.CharacterEncodingFilter
  </filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>encodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

<!--

传参的字符集编码方式

-->

 <filter>
  <filter-name>hibernateFilter</filter-name>
  <filter-class>
   org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
  </filter-class>
 </filter>
 <filter-mapping>
  <filter-name>hibernateFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <filter>

<!--

说明:session是指会话。

OpenSessionInViewFilter类作用

假设在你的应用中Hibernate是通过spring来管理它的session.如果在你的应用中没有使用OpenSessionInViewFilter或者OpenSessionInViewInterceptor。

session会在transaction结束后关闭。
如果你采用了spring的声明式事务模式,它会对你的被代理对象的每一个方法进行事务包装(AOP的方式)。

 <tx:advice id="txAdvice" transaction-manager="transactionManager" >
  <tx:attributes>
     <tx:method name="save*" propagation="REQUIRED" />
     <tx:method name="*" read-only="false" />
  </tx:attributes>
 </tx:advice>

所以给你的感觉是调用这个名为“save”方法之后session就关掉了。
如果应用中使用了OpenSessionInViewFilter或者OpenSessionInViewInterceptor,所有打开的session会被保存在一个线程变量里。在线程退出前通过OpenSessionInViewFilter或者OpenSessionInViewInterceptor断开这些session。这主要是为了实现Hibernate的延迟加载功能。基于一个请求一个hibernate session的原则。

Open Session in View的作用,就是允许在每次的整个request的过程中使用同一个hibernate session,可以在这个request任何时期lazy loading数据。
如果是singleSession=false的话,就不会在每次的整个request的过程中使用同一个hibernate session,而是每个数据访问都会产生各自的seesion,等于没有Open Session in View.
OpenSessionInViewFilter默认是不会对session 进行flush的,并且flush mode 是 never。

事务传播行为类型:

事务传播行为类型

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

-->
  <filter-name>struts2</filter-name>
  <filter-class>
   org.apache.struts2.dispatcher.FilterDispatcher
  </filter-class>
 </filter>
 <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

<!--

struts2过滤器

-->
 </web-app>

附录3:

编程要有规范,保存以save开头,查找以find开头,修改以update开头,控制层以action结尾,业务层以service结尾,数据连接层以到结尾。要见名知意,便于维护(软件的生命周期,维护占很大的人力物力,开发只是生命周期的一小部分,但是是关键的一部分)。

1.dao层有错误,一定要抛到service中进行统一处理
2.jdbc中要使用conn.setAutoCommit(false);conn.rollback(); conn.commit();进行事物的管理

hibernate的事务的管理一般是在一个请求中开一个session,也就是说方法共用一个session,这样进行事务的管理,成功都提交,失败都回滚。但是记住前提是使用一个jdbc连接,不是分布式jta。

要是有不同的数据连接源的话,就要使用JTA_Atomikos进行分布式开发。这样也能达到多个数据源成功都提交,失败都回滚。

附录4:

J2EE+Flex通讯可以使用blazeds,Flex通过RemoteObject调用Java的后台方法。我个人觉得这样的一个最大的好处就是不再需要struts这样之类的框架了,可以直接使用spring中的bean。

SpringFactory类,这个类要实现FlexFactory接口,然后在WEB-INF/flex/services-config.xml中注册改factory。代码如下:

 

  1. < factories> 
  2.  < factory id="springContext" class="com.wangmeng.flex.SpringFactory">< /FACTORY> 
  3. < /FACTORIES> 

这样配置好以后在WEB-INF/flex/remote-config.xml中只要把factory的名字写成和上面配置对应的名字如:springContext,source的值配置为spring中bean的id就可以了。例如:

 

  1. < destination id="userLoginService"> 
  2.   < properties> 
  3.      < factory>springContext< /FACTORY> 
  4.      userLoginService< /SOURCE> 
  5.   < /PROPERTIES> 
  6.  < /DESTINATION> 

附录5:

flex+blazeds+spring+hibernate
配置web.xml

   <!-- 配置spring的监听器 -->
<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value> /WEB-INF/applicationContext.xml</param-value>
</context-param>
    <!-- 开启监听 -->
<listener>
   <listener-class> org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener>

增加一个类 SpringFactory.java

package com.my;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import flex.messaging.FactoryInstance;
import flex.messaging.FlexFactory;
import flex.messaging.config.ConfigMap;
import flex.messaging.services.ServiceException;

public class SpringFactory implements FlexFactory {
private static final String SOURCE = "source";

public void initialize(String id, ConfigMap configMap) {
}

public FactoryInstance createFactoryInstance(String id, ConfigMap properties) {
   SpringFactoryInstance instance = new SpringFactoryInstance(this, id,
     properties);
   instance.setSource(properties.getPropertyAsString(SOURCE, instance
     .getId()));
   System.out.println("SpringSpringSpring" + instance.toString());
   return instance;
}

public Object lookup(FactoryInstance inst) {
   SpringFactoryInstance factoryInstance = (SpringFactoryInstance) inst;
   return factoryInstance.lookup();
}

static class SpringFactoryInstance extends FactoryInstance {
   SpringFactoryInstance(SpringFactory factory, String id,
     ConfigMap properties) {
    super(factory, id, properties);
   }

   public String toString() {
    return "SpringFactory instance for id=" + getId() + " source="
      + getSource() + " scope=" + getScope();
   }

   public Object lookup() {
    ApplicationContext appContext = WebApplicationContextUtils
      .getWebApplicationContext(flex.messaging.FlexContext
        .getServletConfig().getServletContext());
    String beanName = getSource();

    try {
     return appContext.getBean(beanName);
    } catch (NoSuchBeanDefinitionException nexc) {
     ServiceException e = new ServiceException();
     String msg = "Spring service named '" + beanName
       + "' does not exist.";
     e.setMessage(msg);
     e.setRootCause(nexc);
     e.setDetails(msg);
     e.setCode("Server.Processing");
     throw e;
    } catch (BeansException bexc) {
     ServiceException e = new ServiceException();
     String msg = "Unable to create Spring service named '"
       + beanName + "' ";
     e.setMessage(msg);
     e.setRootCause(bexc);
     e.setDetails(msg);
     e.setCode("Server.Processing");
     throw e;
    }
   }
}
}

在services-config.xml中注册SpringFactory

<factories>
   <factory id="spring"
    class="com.my.SpringFactory" />
</factories>

在applicationContext.mxl中注册需要的Bean

<bean id="hello" class="com.my.Hello"></bean>

在remoting-config.xml中将SpringBean公开给Flex客户端

<destination id="hello">
    <properties>
      <factory>spring</factory>
      <source>hello</source>
     </properties>
    </destination>

至此flex于spring的整合就ok。

 

你可能感兴趣的:(ssh)