Struts2 学习笔记

2015年3月7日11:02:55

MVC思想

Strust2的MVC对应关系如下:

在MVC三个模块当中,struts2对应关系如下:

Model:

负责封装应用的状态,并实现应用的功能。通常分为数据模型和业务逻辑模型,数据模型用来存放业务数据,比如订单信息、用户信息等;而业务逻辑模型包含应用的业务操作,比如订单的添加或者修改等。

封装应用状态:某些应用数据封装起来,使得视图只能通过接口获取对应的数据

响应状态查询:对应用的状态改变进行处理

暴露应用功能:暴露接口

通知视图改变:主动向视图传递数据

Controller:

用来控制应用程序的流程和处理视图所发出的请求。当控制器接收到用户的请求后,会将用户的数据和模型的更新相映射,也就是调用模型来实现用户请求的功能;然后控制器会选择用于响应的视图,把模型更新后的数据展示给用户。

接受并验证HTTP请求的数据:对一个url请求,通过Controller将请求分发到指定的处理模块上。

将用户数据域模型的更新相映射:用户数据模型改变并不会立即对应到Model,而是需要controller来分发

选择用于响应的视图:根据配置文件,选择对应与某个模型的视图

View:

用来将模型的内容展现给用户,用户可以通过视图来请求模型进行更新。视图从模型获得要展示的数据,然后用自己的方式展现给用户,相当于提供界面来与用户进行人机交互;用户在界面上操作或者填写完成后,会点击提交按钮或是以其它触发事件的方式,来向控制器发出请求。

解析模型的数据:如velocity的功能

产生HTML的响应:

请求模型的更新:向后台发送表单

发送用户输入给控制器

Struts2工作流程

一个请求在Struts2框架中的处理大概分为以下几个步骤:

  1. 客户端提起一个(HttpServletRequest)请求
  2. 请求被提交到一系列(主要是三层)的过滤器(Filter),如ActionContextCleanUp、其他过滤器、SiteMesh等、FilterDispatcher。注意这里是有顺序的,先ActionContextCleanUp,再其他过滤器(SiteMesh等)、最后到FilterDispatcher。
  3. FilterDispatcher是控制器的核心,就是mvc中controller控制层的核心。FilterDispatcher进行初始化并启用核心doFilter
  4. ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类.
  5. ActionProxy创建一个ActionInvocation的实例,同时ActionInvocation通过代理模式调用Action。但在调用之前ActionInvocation会根据配置加载Action相关的所有Interceptor。(Interceptor是struts2另一个核心级的概念)
  6. Interceptor 的调度流程大致如下:
    1.
    ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。
    2. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor。

整体流程

l  客户端提交一个HttpServletRequest请求(action或JSP页面)。

l  请求被提交到一系列Filter过滤器,如ActionCleanUp和FilterDispatcher等。

l  FilterDispatcher是Struts2控制器的核心,它通常是过滤器链中的最后一个过滤器。

l  请求被发送到FilterDispatcher后,FilterDispatcher询问ActionMapper时候需要调用某个action来处理这个Request。

l  如果ActionMapper决定需要调用某个action,FilterDispatcher则把请求交给ActionProxy进行处理。

l  ActionProxy通过Configuration Manager询问框架的配置文件struts.xml,找到调用的action类。

l  ActionProxy创建一个ActionInvocation实例,通过代理模式调用Action。

l  action执行完毕后,返回一个result字符串,此时再按相反的顺序通过Intercepter拦截器。

l  最后ActionInvocation实例,负责根据struts.xml中配置result元素,找到与之相对应的result,决定进一步输出。

Action

Struts2的action生命周期

Struts2的action接口隔离

Struts2中的Action,并不需要依赖于特定的Web容器。我们看不到类似HttpServletRequest,HttpServletResponse等Web容器相关的对象。

提问:Struts2Action并不带有任何Web容器相关的对象,Action又是如何工作在Web容器中的呢?

虽然Struts2的Action只是一个非常普通的Java对象,并不具备任何Web容器的特质,但是我们需要把Action放到一个更加大的环境中来看。事实上,Struts2为Action的执行,准备了完整的数据环境和执行环境。而这个执行环境,就保证了Action在Web容器中的顺利运行。

在Struts2中,每个Http的请求,会被发送到一个Filter。而这个Filter,就会针对每个请求,创建出一个代码的执行环境,并在这个基础上,为每个执行环境配备与之对应的数据环境,这个数据环境中的内容,就来自于Web容器中的一个又一个对象。这样,就能够顺利调用Action执行代码而无需担心它是否运行在Web容器中了。

提问:Struts2Action并不带有任何Web容器相关的对象,Action中又如何与Web容器进行通信并获取Web容器的相关对象呢?

刚刚我们提到Struts2会为每个Http的请求建立一个执行环境和数据环境。其中,数据环境就成为了Action获取Web容器的基础。所以,当Action需要获取Web容器的相关对象,需要通过数据环境来进行。

Struts2设置的优点

1. 使得Struts2的Action非常易于测试

如果我们完全不考虑Action的执行环境,仅仅把Action看作一个普通的Java对象,那么我们甚至可以直接new一个Action的对象,通过执行其中的方法完成测试。这样,我们就不需要任何的Mock,来模拟Web容器的环境。

2. 结合Action的执行环境,使得Struts2在Control这个层次上,能够定义更加丰富的执行层次

因为Action是一个普通的Java类,而不是一个Servlet类,完全脱离于Web容器,所以我们就能够更加方便地对Control层进行合理的层次设计,从而抽象出许多公共的逻辑,并将这些逻辑脱离出Action对象本身。事实上,Struts2也正是这么做的,无论是Interceptor,还是Result,其实都是抽象出了Action中公共的逻辑部分,将他们放到了Action的外面,从而更加简化了Action的开发。

3. 使得Struts2的Action看上去更像一个POJO,从而更加易于管理

Struts2的Action是一个线程安全的对象。而Web容器传递过来的参数,也会传递到Action中的成员变量中。这样,Action看上去就更像一个POJO,从而能够方便的被许多对象容器进行管理。比如说,你可以非常方便得把Action纳入到Spring的容器中进行管理。

数据交互上下文 ActionContext(BeatContext)

由于Action是应对于一个又一个的URL请求,所以ActionContext应该具备以下的特性:

1. ActionContext应成为Action与Web容器之间的桥梁

2. ActionContext中应该保存有针对某个请求的详细信息

3. ActionContext应该是一个线程安全的类对象

Struts2拦截器与过滤器

拦截器和过滤器的区别:

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调

2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器

3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

过滤器

首先讨论struts2过滤器,struts2的主要过滤器是FilterDispatcher,相当于MVC框架当中的controller,有如下几个功能:

(1)执行Actions:过滤器通过ActionMapper对象,来判断是否应该被映射到Action.如果mapper对象指示他应该被映射,过滤链将会被终止,然后Action被调用。这一点非常重要,如果同时使用SiteMesh filter,则SiteMesh filter应该放到该过滤器前,否则Action的输出将不会被装饰。

(2)清除ActionContext:过滤器为了确保内存溢出,会自动的清除ActionContext。这可能会存在一些问题,在和其它的框架集成时,例如SiteMesh(一致的web页面布局框架,类似装饰器)。ActionContextCleanUp提供了怎么处理这些问题的一些信息。在配置了FilterDispatcher的前提下已经配置了ActionContextCleanUp拦截器。

(3)维护静态内容:过滤器也会维护在Struts2中使用的一些公共的静态的内容,例如JavaScript文件,CSS文件等。搜索/struts/*范围内的请求,然后将/struts/后面的值映射到一些struts的公共包中,也可以在你的类路径中搜索。

默认情况下会去查找以下包:org.apache.struts2.static.template。这样你只用请求/struts/xhtml/styles.css,XHTML UI主题默认的样式表将会被返回。同样,AJAX UI组件需要的JavaScript文件,也可以在org.apache.struts2.static包中被找到。如果你想加入其它被搜索的包,在web.xml中设置filter时,通过给"actionPackages"初始参数一个逗号隔开的包列表值来设定。

(4)清除request生命周期内的XWork的interceptors

自定义过滤器

应该知道如果我们自己定义过滤器的话, 是要放在strtus2的过滤器之前的, 如果放在struts2过滤器之后,你自己的过滤器对action的过滤作用就废了,不会有效!除非你是访问jsp/html!

那我现在有需求, 我必须使用Action的环境,而又想在执行action之前拿filter做一些事, 用FilterDispatcher是做不到的.

那么StrutsPrepareAndExecuteFilter可以把他拆分成StrutsPrepareFilter和StrutsExecuteFilter,可以在这两个过滤器之间加上我们自己的过滤器.!

过滤器也可以自己定义,在使用新的StrutsPrepareAndExecuteFilter作为核心过滤器的情况下,可以将自定义的过滤器放在各种位置上。

具体的配置在web.xml当中进行配置。

拦截器

在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下所示:

<interceptor-ref name="checkbox">
 
<param name="uncheckedValue">0</param>
</interceptor-ref>
<interceptor-ref
name="defaultStack"/>(
必须加,否则出错)

Strust2拦截器构成拦截器栈,在使用过程中,相当于递归调用这些拦截器的intercept方法。通常我们采用struts2的默认拦截器,自己开发,则要遵循以下的步骤:

1 自定义一个实现Interceptor接口(或者继承自AbstractInterceptor)的类。

2 在strutx.xml中注册上一步中定义的拦截器。

3 在需要使用的Action中引用上述定义的拦截器,为了方便也可将拦截器定义为默认的拦截器,这样在不加特殊声明的情况下所有的Action都被这个拦截器拦截。

开发

Interceptor接口声明了三个方法:

public interface Interceptor extends
Serializable {

void destroy();

void init();

String intercept(ActionInvocation invocation) throws Exception;

}

Init方法在拦截器类被创建之后,在对Action镜像拦截之前调用,相当于一个post-constructor方法,使用这个方法可以给拦截器类做必要的初始话操作。

Destroy方法在拦截器被垃圾回收之前调用,用来回收init方法初始化的资源。

Intercept是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用invocation.invoke()方法即可,在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。如果不需要调用后续的方法,则返回一个String类型的对象即可,例如Action.SUCCESS。另外AbstractInterceptor提供了一个简单的Interceptor的实现。

注册拦截器

<interceptors>

<interceptor name="login" class="com.jpleasure.teamware.util.CheckLoginInterceptor"/>

<interceptor-stack
name="teamwareStack">

<interceptor-ref
name="login"/>

<interceptor-ref
name="defaultStack"/>

</interceptor-stack>

</interceptors>

将上述拦截器设定为默认拦截器

<default-interceptor-ref
name="teamwareStack"/>

这样在后续同一个package内部的所有Action执行之前都会被login拦截。

每一个拦截器都有两个默认的参数:

excludeMethods - 过滤掉不使用拦截器的方法和

includeMethods – 使用拦截器的方法。

需要说明的几点:

1 拦截器执行的顺序按照定义的顺序执行

2 使用默认拦截器配置每个Action都需要的拦截器堆栈

3 如何访问HttpServletRequest,HttpServletResponse或者HttpSession

有两种方法可以达到效果,使用ActionContext:

Map attibutes =
ActionContext.getContext().getSession();

或者实现相应的接口:

HttpSession           SessionAware

HttpServletRequest    
ServletRequestAware

HttpServletResponse   
ServletResponseAware

剩余部分

集成spring与hibernate

OGNL与标签

高级主题

Struts2 学习笔记(概述)的更多相关文章

  1. Struts2学习笔记⑧

    今天是Struts2学习笔记的最后一篇文章了.用什么做结尾呢,这两天其实还学了很多东西,没有记录下,今天就查漏补缺一下. 文件上传与下载.FreeMarker以及昨天没做完的例子 文件上传与下载 文件 ...

  2. Struts2学习笔记①

    Struts2 学习笔记① 所有的程序学习都从Hello World开始,今天先跟着书做一个HW的示例. Struts2是一套MVC框架,使用起来非常方便,接触到现在觉得最麻烦的地方是配置文件.我的一 ...

  3. Struts2学习笔记NO.1------结合Hibernate完成查询商品类别简单案例(工具IDEA)

    Struts2学习笔记一结合Hibernate完成查询商品类别简单案例(工具IDEA) 1.jar包准备 Hibernate+Struts2 jar包 struts的jar比较多,可以从Struts官 ...

  4. TCP/IP详解学习笔记- 概述

    TCP/IP详解学习笔记(1)-- 概述1.TCP/IP的分层结构      网络协议通常分不同层次进行开发,每一层分别负责不同的同信功能.TCP/IP通常被认为是一个四层协议系统.      如图所 ...

  5. struts2学习笔记 ⑤

    拦截器初探 昨天临睡觉之前看了看拦截器,也在昨天的学习笔记里面胡诌诌了几句,今天就来好好的会会拦截器这个东西.实际上拦截器是一种模块实现的机制<起码我是这么体会的>(至于说书里面说体现了A ...

  6. java web jsp学习笔记--概述-常用语法,指令,动作元素,隐式对象,域对象

     JSP学习笔记 1.什么是jsp JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP/Servlet规范.JS ...

  7. [struts2学习笔记] 第二节 使用Maven搞定管理和构造Struts 2 Web应用程序的七个步骤

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/40303897 官方文档:http://struts.apache.org/releas ...

  8. struts2学习笔记(五)—— OGNL

    一.OGNL概述 1.1 什么是OGNL OGNL的全称是对象图导航语言( object-graph Navigation Language),它是一种功能强大的开源表达式语言,使用这种表达式语言,可 ...

  9. Struts2学习笔记 国际化(Internationalization)

    概述 国际化(Internationalization),通途的讲,就是让软件实现对多种语言的支持.可以通过简单的设置就可以从一种语言切换到另一种语言.用的最多的地方就是在应用程序的界面表示上.我们经 ...

随机推荐

  1. matlab 图像分块及恢复

    1. block_divide % 返回的块向量构成的矩阵,其维度信息为 K^2 * N,每一列由块构成的列向量 function P = block_divide(I, K) r = size(I, ...

  2. Python 标准库 —— uuid(生成唯一 ID)

    有时我们在百度贴吧,在一个网站,保存网页上的一些图片时,图片名有时会是一串很长的数字和字母组成的,但无一例外,图像之间不会出现重名.这个唯一的 id,一般通过 uuid 的方式获得,uuid 根据的是 ...

  3. sql这两个表和查询的组合yii通过使用数据库查询

    sql两个表的组合查询  使用 join on 比如:两个表查询: select u.username, t.title from user u join task t on u.id = t.id; ...

  4. 探究Promise的实现

    最终答案在一个类库里,地址 https://github.com/yahoo/ypromise 这个类库也有问题,就是下面这道面试题在IE9里实现不一致,类库里还是用了setTimeout.去年尝试用 ...

  5. android高仿人人网

    经过几个月的努力,终于基本完成了人人API拥有的所有功能,界面采用仿照人人梦想版5.13制作,其中资源文件也采用人人的APK文件资源,完成的功能及知识点如下: 1.通过三种动画仿照出人人引导页的放大切 ...

  6. 道量化交易程序猿(25)--Cointrader之MarketData市场数据实体(12)

    转载注明出处:http://blog.csdn.net/minimicall.http://cloudtrade.top/ 前面一节我们说到了远端事件.当中.市场数据就属于远端事件.市场数据有什么?我 ...

  7. March 29th, 2015, Thread Name is odd by increasing 1

    public class Fabric extends Thread{ public static void main(String args[]){ Thread t = new Thread(ne ...

  8. ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 配置 EF 框架服务 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 EF 框架服务 上一章节中我们了解了 Entity ...

  9. Qt Installer Framework 3.0.1 Released(功能比较强)

    We are happy to announce the release of Qt IFW 3.0.1. 3.0.1 is fully compatible with 2.0.5, which me ...

  10. XP双网卡不能上网的问题

    转载. 现在很多本本都是双网卡配置,让两个网卡分别负责连接内外网能够加快上网速度和连接稳定,但不少网友照做后会出现无法上网的情况,这是由于默认网关冲突所导致的.那么该如何处理让双网卡各行其是,互不干扰 ...