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. jeesuite分布式框架环境搭建

    一.简述 这是菜鸟走向开源的第一步.开源项目jeesuite:http://git.oschina.net/vakinge/jeesuite-libs jeesuite是托管在码云上的开源项目,是一个 ...

  2. 允许svn服务与WINDOWS自己主动启动

    曾经的svnserve要想成为windows服务,必须依赖于svnservice或其它工具. 从Subversion1.4開始,Subversion本身就集成了Windows服务的工具. 将svn设置 ...

  3. js 图片缩显

    <script language="javascript"> var flag=false;  function MyImage(Img){  var image=ne ...

  4. Android--MVP设计模式实践

    MVP设计模式是android开发讨论的很火的一个话题,我对设计模式也有一些拙见,为了实践我的一些想法,我在我最新开发的产品中将我心目中的MVP设计模式进行了实践,最后得到了这样的架构. 特点:简单, ...

  5. node lesson4--eventproxy不懂

    var express = require('express'); var superagent = require('superagent'); var cheerio = require('che ...

  6. Python 爬虫 —— scrapy

    0. 创建网络爬虫的常规方法 进入命令行(操作系统的命令行,不是 python 的命令行) windows:cmd ⇒ c:\Uses\Adminstrator> Linux:$ 执行:scra ...

  7. flask-mail发送邮件始终失败

    from flask_mail import Mail,Message from flask import Flask import os app=Flask(__name__) app.config ...

  8. 使用bcc32做在windowXP上qt3.2.1编译环境的配置

    1.安装borland C++编译器,编译器文件所在目录下的文件如下: 其中bcc32.cfg和ilink32.cfg文件是自己加进去的,bcc32.cfg内容是-I"C:\Borland\ ...

  9. python3操作注册表设置/取消IE代理

    import io, sys, time, re, os import winreg def enableProxy(IP, Port): proxy = IP + ":" + s ...

  10. Qt on Android 资源文件系统qrc与assets

    使用 Qt 为 Android 开发应用时,有时我们的应用会携带一些资源文件,如 png . jpg 等,也可能有一些配置文件,如 xml 等,这些文件放在哪里呢?有两种方式:qrc和assets,咱 ...