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. NLP & 中文分词

    NLP & 中文分词 中文分词 (Word Segmentation, WS) 指的是将汉字序列切分成词序列. 中文自然语言处理系统 https://www.ltp-cloud.com/int ...

  2. 第217天:深入理解Angular双向数据绑定的原理

    一.理解angular双向数据绑定 双向绑定是新的前端框架中频繁出现的一个新词汇,也是mvvm的核心原理.angularjs五条核心信念中的数据驱动,便是由双向绑定进行完成. 那么什么是双向绑定,下面 ...

  3. ASP.NET MVC 模型绑定

    模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: ...

  4. c++11 委托构造

    c++11 委托构造 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #includ ...

  5. MT【149】和式变形

    (2018浙江省赛14题)将$2n(n\ge2)$个不同的整数分成两组$a_1,a_2,\cdots,a_n;b_1,b_2,\cdots,b_n$.证明:$\sum\limits_{1\le i\l ...

  6. 【刷题】BZOJ 3626 [LNOI2014]LCA

    Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先. ...

  7. 【BZOJ3675】【Apio2014】序列分割

    Description 传送门 Solution ​ 之前我也遇到过一次这种"两段之和乘积作为贡献"的问题:考虑把这一种\((\sum) *(\sum)\)的形式拆括号,就可以发现 ...

  8. 【转载】dfs序七个经典问题

    作者:weeping 出处:www.cnblogs.com/weeping/ 原文链接 https://www.cnblogs.com/weeping/p/6847112.html 参考自:<数 ...

  9. nginx之编译安装

    一.认识nginx 常用的web服务有Apache.IIS(windows系统).Lighttpd.Tomcat.Nginx等.Nginx是一个开源的,支持高性能.高并发的www服务和代理服务软件.它 ...

  10. 【bzoj2002】 Hnoi2010—Bounce 弹飞绵羊

    http://www.lydsy.com/JudgeOnline/problem.php?id=2002 (题目链接) 题意 数轴上${n}$个点,每个点有一个权值${a_i}$,如果到达这个点,接下 ...