SSH 框架整合技术:
  3. Spring与Struts2整合(对比SpringWeb):

    Spring 与 Struts2 整合的目的有两个:
      (1)在 Struts2 的 Action 中,即 View 层,获取到 Service。然后就实现了在 Struts2 项目中 View 层、Service 层、Dao 层的联通。
      (2)将 Action 实例交由 Spring 容器管理。

    代码详解:

    (1) 将 Servlet 修改成 Action:

 package com.tongji.actions;

 import com.tongji.beans.Student;
import com.tongji.service.IStudentService; public class RegisterAction {
private String name;
private int age; //声明Service对象
private IStudentService service; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public IStudentService getService() {
return service;
} public void setService(IStudentService service) {
this.service = service;
} public String execute() {
Student student = new Student(name, age);
service.addStudent(student);
return "success";
}
}

    注意:直接将Service作为Action的属性

    (2) 在 Spring 配置文件中注册 Action 的 Bean
      在 Spring 的配置文件中将 Action 作为一个普通 Bean 进行定义,并在配置文件中完成 Service 的注入。即添加如下代码:

          <!-- 注册Action:必须指定Action的scope为prototype,因为Action是多例的 -->
          <bean id="registerAction" class="com.tongji.actions.RegisterAction" scope="prototype">
              <property name="service" ref="studentService"/>
          </bean>

    (3) Struts2 配置文件中的 class 使用伪类名
      Struts2 配置文件中的<action/>标签的 class 属性值不再是 Action 的全类名了,而是个伪类名:Spring 配置文件中该 Bean 的 id 名。

 <?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="ssh" namespace="/test" extends="struts-default">
<!-- class的值是Spring容器中Action的Bean的id值,此时的class的属性值称为 伪类 -->
<action name="register" class="registerAction">
<result>/welcome.jsp</result>
</action>
</package>
</struts>

    (4) 修改前端页面:

 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html>
<head>
<title>index</title>
</head> <body>
<form action="test/register.action" method="POST">
name:<input type="text" name="name"/><br>
age:<input type="text" name="age"/><br>
<input type="submit" value="submit"/>
</form>
</body>
</html>
 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html>
<head>
<title>welcome</title>
</head> <body>
welcome you!
</body>
</html>

    (5) 其余代码都不变,发布运行即可。

  补充问题:当将事务织入到 Service 层后,在 Dao 层通过 load()等具有延迟加载功能的方法加载实体时,会出现异常。

  View 层要读取一个对象的某属性值,所以在 View 层调用了 Service 层的对象获取方法。此时 Service 层就会去调用 Dao 层,欲从 DB 中读取数据。但由于 Service 层并非是真正需要数据的一方,即 Servcie 层并非真正需要数据的详情。又由于 Dao 层使用了延迟加载技术,所以返回给 Service 层一个数据为空的代理对象。当 Service 获取到了这个对象后,马上将这个对象返回给了 View 层。Service 层认为任务完成,所以将事务进行了关闭。由于 Session 必须在事务环境下运行,且事务在提交或回滚后,会首先将Session 关闭,而后关闭事务。所以事务关闭前,Session 就已经消失。当 View 层收到 Service 层发送来的对象,并使用其详情时,发现为空。此时 View 层向 Service 层发出进行真正查询请求时,Service 层的 Session 已经不存在,所以,会报出 Session 为空的异常。

  解决办法:

  问题的主要原因是事务应用在业务层,而延迟加载使得对 Hibernate 的 Session 的连续使用放在了 View 层。若要 Session 不进行自动关闭,必须使其所在的事务环境不能在 Service 层就结束,所以可以将 Session 的开启放在 View 层。  
    只需在 web.xml 中注册一个过滤器 OpenSessionInViewFilter(开启 Session 在 View),只要用户提交请求,就会先执行该过滤器,将 Session 开启。

 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
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_3_0.xsd">
<!-- 指定Spring配置文件的名称及位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param> <!-- 注册监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 注册OpenSessionInViewFilter,要求其必须在Struts启动项这个Filter的前面注册 -->
<filter>
<filter-name>OpenSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
<!-- 默认OpenSessionInViewFilter加载的SessionFactory名称为sessionFactory
这里指定自己定义的SessionFactory的名称,让OpenSessionInViewFilter加载 -->
<!-- <init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>mySessionFactory</param-value>
</init-param> -->
</filter>
<filter-mapping>
<filter-name>OpenSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!-- 注册Struts2启动项 -->
<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> <welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> </web-app>

    注册过滤器时需要注意:
    (1)该过滤器会自动从 Spring 配置文件中查找名称为 sessionFactory 的 Bean。若定义的不是这个名称,则需通过初始化参数<init-param/>进行指定。

    
    (2)该过滤器应注册在 StrutsPrepareAndExecuteFilter 的前面,即在进入 Struts2 之前先执行过滤,否则还会出现noSession的问题。其注册顺序可以从 Struts2 的流程图中看出。

    
    过滤器的执行都是通过过滤器链串起来执行的,即当前的 Filter 通过在自己的 doFilter() 方法中执行 chain.doFilter()来调用执行下一下过滤器。
      查看 StrutsPrepareAndExecuteFilter 的源码可以看出,只有当没有 Action 要执行时,才可能会执行其它的过滤器,即调用 chain.doFilter()。否则,只要有 Action 能够匹配上执行,那么就没有 chain.doFilter()方法要执行了,即 Struts2 的 StrutsPrepareAndExecuteFilter 将成为最后一个被执行的 Filter。所以,只有将 OpenSessionInViewFilter 放到 Struts2 的过滤器StrutsPrepareAndExecuteFilter 的前面才会被执行到。
    

    至此,SSH整合就结束了。

Spring4笔记12--SSH整合3--Spring与Struts2整合的更多相关文章

  1. Spring与Struts2整合VS Spring与Spring MVC整合

    Spring与Struts2整合,struts.xml在src目录下 1.在web.xml配置监听器 web.xml <!-- 配置Spring的用于初始化ApplicationContext的 ...

  2. spring与struts2整合出现错误HTTP Status 500 - Unable to instantiate Action

    在进行spring和struts2整合的时候因为大意遇到了一个问题,费了半天神终于找到了问题所在,故分享出来望广大博友引以为戒!! 我们都知道在spring和struts2整合时,spring接管了a ...

  3. SSM整合(2): spring 与 mybatis 整合

    在进行完spring与springmvc整合之后, 继续 spring与mybatis的整合. 既然是操作数据库, 那必然不能缺少了连接属性 一. db.properties jdbc.driver= ...

  4. Spring与Struts2整合时action自动注入的问题

    当Struts和Spring框架进行整合时,原本由action实例化对象的过程移交给spring来做(这个过程依赖一个叫struts2-spring-plugin的jar包,这个包主要的功能就是实现刚 ...

  5. Spring与Struts2整合

    Spring与Struts2为什么要整合呢? 把Action实例交给Spring来管理!! 1.单独测试Struts是否添加成功(jar包和配置文件),先单独测试,不要整合之后再测试,容易出问题 we ...

  6. SSM整合(1): spring 与 springmvc 整合

    久没有写博客了, 今年事情太多了, 也没了心思. 去深圳出差,  更重要的结婚的事情, 一茬接一茬. 好在最近闲暇一些, 就想记录一些曾经困扰过我的问题(现在用spring boot真是太方便了, 很 ...

  7. Spring注解与Spring与Struts2整合

    @Component @Controller @Service @Repository 四大注解作用基本一样,只是表象在不同层面 @Resource @Scope Struts2与Spring整合:1 ...

  8. Spring和Struts2整合

    目的:spring容器管理Action类,代替Servlet 步骤:主要在配置文件 Struts2: 添加支持spring的jar包, 配置<action class="Action类 ...

  9. spring+hibernate+Struts2 整合(全注解及注意事项)

    最近帮同学做毕设,一个物流管理系统,一个点餐系统,用注解开发起来还是很快的,就是刚开始搭环境费了点事,今天把物流管理系统的一部分跟环境都贴出来,有什么不足的,请大神不吝赐教. 1.结构如下 2.jar ...

  10. spring与struts2整合出现常见错误

    错误信息 严重: Exception starting filter struts2 Unable to load configuration. - bean - jar:file:/F:/Strut ...

随机推荐

  1. Java容器深入浅出之HashSet、TreeSet和EnumSet

    Java集合中的Set接口,定义的是一类无顺序的.不可重复的对象集合.如果尝试添加相同的元素,add()方法会返回false,同时添加失败.Set接口包括3个主要的实现类:HashSet.TreeSe ...

  2. [BinaryTree] AVL树、红黑树、B/B+树和Trie树的比较

    转自:AVL树.红黑树.B/B+树和Trie树的比较 AVL树 最早的平衡二叉树之一.AVL是一种高度平衡的二叉树,所以通常的结果是,维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应 ...

  3. mybatis的setting

    在mybaits中,setting的的配置参数如下(如果不在配置文件中配置将使用默认值): 设置参数 描述 有效值 默认值 cacheEnabled 该配置影响的所有映射器中配置的缓存的全局开关 tr ...

  4. HDU4726——Kia's Calculation——2013 ACM/ICPC Asia Regional Online —— Warmup2

    题目的意思是给你两个数字(多达10^6位) 做加法,但是有一点,没有进位(进位不算,相当于这一位相加后对10取模) 你可以任意排列两个数字中的每一位,但是不能是0开头. 现在题目要求以这种不进位的算法 ...

  5. bzoj2095-Bridge

    题意 一个 \(n\) 个点 \(m\) 条边的图,每条边双向都有权值(可能不一样).求从 1 开始,经过所有点,经过所有边一次且仅一次(即一定要经过这条边的某个方向)回到 1 的路径上权值最大的最小 ...

  6. BZOJ5312 冒险(线段树)

    记录区间and/or,修改时如果对整个区间影响都相同就打标记,否则递归.复杂度不太会证. #include<iostream> #include<cstdio> #includ ...

  7. win10与Ubantu双系统:Linux下开启FTP服务器与创建无线热点(实现文件共享)

    如何在win系统下使用filelizza这个软件搭建FTP服务器,然后建立一个无线局域网,让平板终端连接以后,访问电脑硬盘的文件. 如果是只在win7环境下,一切都很简单,按照上文提供的教程就可以实现 ...

  8. DSU模板(树的启发式合并)

    摘自Codeforces博客 With dsu on tree we can answer queries of this type: How many vertices in subtree of ...

  9. 【BZOJ1079】【SCOI2008】着色方案

    Time Limit: 10 Sec Memory Limit: 162 MB Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci ...

  10. php版本的code review软件

    phabricator, http://www.oschina.net/p/phabricator