ModelDrivenInterceptor

该拦截器处于defaultStack中的第九的位置,在ScopedModelDrivenInterceptor拦截器之后,要使该拦截器有效的话,Action必须实现ModelDriven接口,该接口就一个方法:getModel(),ModelDrivenInterceptor拦截器主要做的事就是调用Action的getModel()方法然后把返回的model压入值栈(如果不为null)。如果Action实现了ScopedModelDriven接口也就实现了ModelDriven接口,因为ScopedModelDrivenInterceptor在执行的过程肯定会返回一个model对象再调用Action的setModel(model)方法,如果Action对model进行了接收,那么在执行到ModelDrivenInterceptor拦截器的时候,Action的getModel()方法返回的就是ScopedModelDrivenInterceptor拦截器设置进去的值,已经不为null了,所以该model自然就会压入值栈。下面是该拦截器intercept方法源码:

@Override
public String intercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();//获取当前正在执行的Action
//如果Action实现了ModelDriven接口
if (action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven) action;
ValueStack stack = invocation.getStack();
Object model = modelDriven.getModel();//通过getModel方法获取model
if (model != null) {//如果model不为null则把model压入值栈
stack.push(model);
}
if (refreshModelBeforeResult) {//在执行Result之前是否要更新model对象,默认为false
invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
}
}
return invocation.invoke();//调用下一个拦截器
}

该方法逻辑很简单,正如前所说的一样,就是把getModel方法返回的结果压入值栈而已,我们一般实现这个接口是利用压入值栈的model对象接收从页面提交过来的数据,有很多时候我们是在Action中写属性来接收参数的,因为Action也是在值栈中,而struts2在赋值参数的时候是在值栈从栈顶往栈底寻找有相应setter方法的对象,而这时model压入了值栈,它是处于栈顶的,所以从页面提交过来的参数也就被model对象接收了。这种方式呢model对象有点像struts1.X里面formbean对象的功能。

ModelDrivenInterceptor拦截器中还有个名为refreshModelBeforeResult的属性,用于设置在执行Result之前是否要更新model对象,默认值是false也就不会去更新,我们有可能在Action的执行过程将model这个引用变量指向了另外一个对象,如果你把refreshModelBeforeResult设置了为true,那么在Result执行之前PreResultListener就会用这个新的对象将值栈中的对象替换,达到更新效果。

PreResultListener是一种监听器由ActionInvocation对象进行注册,在Result执行之前会执行该种监听器的beforeResult方法。虽然在defaultStack中,struts2是不会在ActionInvocation中注册这个RefreshModelBeforeResult监听器的,我们还是去简单看一下:

protected static class RefreshModelBeforeResult implements PreResultListener {
private Object originalModel = null;
protected ModelDriven action; public RefreshModelBeforeResult(ModelDriven action, Object model) {
this.originalModel = model;
this.action = action;
} public void beforeResult(ActionInvocation invocation, String resultCode) {
ValueStack stack = invocation.getStack();//获取值栈
CompoundRoot root = stack.getRoot();//获取值栈的root对象 boolean needsRefresh = true;
Object newModel = action.getModel();//从Action中获取新的model对象 // Check to see if the new model instance is already on the stack
for (Object item : root) {
if (item.equals(newModel)) {//如果新的model对象与旧的相同则不刷新
needsRefresh = false;
}
} // Add the new model on the stack
if (needsRefresh) {//如果要刷新 // Clear off the old model instance
if (originalModel != null) {
root.remove(originalModel);//先移除旧model
}
if (newModel != null) {
stack.push(newModel);//将新model对象压入值栈
}
}
}
}

RefreshModelBeforeResult实现了PreResultListener接口,是ModelDrivenInterceptor的一个静态内部类,在执行Result之前执行其beforeResult方法
如何进行刷新的很简单相信大家都看得懂。

intercept方法最后一句invocation.invoke();调用下一个拦截器......

struts2 18拦截器详解(十)的更多相关文章

  1. struts2 18拦截器详解(七)

    ChainingInterceptor 该拦截器处于defaultStack第六的位置,其主要功能是复制值栈(ValueStack)中的所有对象的所有属性到当前正在执行的Action中,如果说Valu ...

  2. struts2 18拦截器详解(九)

    ScopedModelDrivenInterceptor 该拦截器处于defaultStack第八的位置,其主要功能是从指定的作用域内检索相应的model设置到Action中,该类中有三个相关的属性: ...

  3. struts2 18拦截器详解(五)

    I18nInterceptor 该拦截器处理defaultStack第四的位置,是用来方便国际化的,如果说我们的一个Web项目要支持国际化的话,通常的做法是给定一个下拉框列出所支持的语言,当用户选择了 ...

  4. 通俗易懂之SpringMVC&Struts2前端拦截器详解

    直接进入主题吧!一,配置Struts2的拦截器分两步走1配置对应的拦截器类:2在配置文件Struts.xml中进行配置拦截器同时在Strust2中配置拦截器类有三种方法1实现Interceptor接口 ...

  5. struts2内置拦截器和自定义拦截器详解(附源码)

    一.Struts2内置拦截器 Struts2中内置类许多的拦截器,它们提供了许多Struts2的核心功能和可选的高级特 性.这些内置的拦截器在struts-default.xml中配置.只有配置了拦截 ...

  6. Struts2 之 modelDriven & prepare 拦截器详解

    struts2 ModelDriven & Prepareable 拦截器 前面对于 Struts2 的开发环境的搭建.配置文件以及 Struts2 的值栈都已经进行过叙述了!这次博文我们讲解 ...

  7. Struts2拦截器详解

    一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的    拦截器对象,然后串成一个列 ...

  8. Struts2中的拦截器详解

    exception:异常拦截器,拦截异常aliasservletConfig18nprepare:预备拦截器,这个拦截器就是为了ModelDriven准备对象的,若Action类实现了preparab ...

  9. [转]SpringMVC拦截器详解[附带源码分析]

      目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:ht ...

随机推荐

  1. 如何判断来访的IP是否是百度蜘蛛ip?

    网站日志是可以真实体现网站的状态,通过网站日志我们可以清楚的看到网站每天有多少访客,每天有多少蜘蛛来抓取网站的数据,哪些数据被蜘蛛抓取了.哪些页面在请求数据的时候发现了错误.这些都是可以通过状态码来进 ...

  2. 20172306《Java程序设计与数据结构》第十周学习总结

    20172306<Java程序设计>第十周学习总结 教材学习内容总结 本章主要的讲的是集合有关的知识: 1.集合与数据结构 - 集合是一种对象,集合表示一个专用于保存元素的对象,并该对象还 ...

  3. websocket activemq

    websocket:应用与服务端保持长连接 不停通信 activemq:偶发通信  心跳机制

  4. Shortest Unsorted Continuous Subarray LT581

    Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...

  5. linux上的工具或软件

    1.下载软件 yum install axelaxel http://mirror.cse.iitk.ac.in/archlinux/iso/2015.04.01/archlinux-2015.04. ...

  6. 秒懂 this

    一:全局执行 console.log(this); // Window 可以看出在全局作用域中 this 指向当前的全局对象 Window. 二:函数中执行 1.非严格模式中 function fun ...

  7. 软件测试基础Ⅲ(osi7层协议,测试模型,LoadRunner组件,软件质量模型)

    osi7层开放式系统互连网络模型 1.物理层:主要定义物理设备标准,如网线的接口类型.光纤的接口类型.各种传输介质的传输速率等.它的主要作用是传输比特流(就是由1.0转化为电流强弱来进行传输,到达目的 ...

  8. mybatis学习三 数据库连接池技术

    1.在内存中开辟一块空间,存放多个数据库连接对象.就是Connection的多个实例2. 连接池技术有很多,c3p0,dbcp,druid,以及JDBC Tomcat Pool, JDBC Tomca ...

  9. Python之内置函数一

    一:绝对值,abs i = abs(-123) print(i) # 打印结果 123 二:判断真假,all,与any 对于all # 每个元素都为真,才是True # 假,0,None," ...

  10. 初识python函数

    一.函数 1.什么是函数 函数是对功能或者动作的封装 2.函数的语法和定义 def 函数名(): 函数体 调用: 函数名() 3.关于函数的返回值 return :  返回 1.当程序没写过retur ...