ScopedModelDrivenInterceptor

该拦截器处于defaultStack第八的位置,其主要功能是从指定的作用域内检索相应的model设置到Action中,该类中有三个相关的属性:
scope:从哪里获取model,有两个值,一是request,二是session,默认值为request
name:在scope中检索model的key
className:model类的名称,也就是该model是什么类型

虽然这三个参数都可以进行设置,但是在defaultStack中struts2并没有为其赋值,所以初始值这三个属性都为null。

下面我们去看一个ScopedModelDriven接口,该接口继承自ModelDriven接口,实现了ScopedModelDriven接口也就实现了ModelDriven,所以当前Action也会有ModelDriven的特性,ModelDriven在下一个拦截器中介绍。ScopedModelDriven接口中相当于有四个方法:
1.getModel() -->用于Action获取model
2.setModel() -->提供给ScopedModelDrivenInterceptor为Action设置model
3.getScopeKey() -->用于Action获取model存储在作用域中的key,这里对应了ScopedModelDrivenInterceptor中的name属性
4.setScopeKey() -->提供给ScopedModelDrivenInterceptor为Action设置model存储的key

下面是ScopedModelDrivenInterceptor的intercept方法源码:

@Override
public String intercept(ActionInvocation invocation) throws Exception {
Object action = invocation.getAction();//获取当前正在执行的Action
//如果Action实现了ScopedModelDriven接口
if (action instanceof ScopedModelDriven) {
ScopedModelDriven modelDriven = (ScopedModelDriven) action;//强转
if (modelDriven.getModel() == null) {//如果返回为null,如果不为null的话是不会去修改该Action中model属性的
ActionContext ctx = ActionContext.getContext();//获取ActionContext
ActionConfig config = invocation.getProxy().getConfig();//获取Action配置
//model类名,初始值为null
String cName = className;
if (cName == null) {
try {
Method method = action.getClass().getMethod(GET_MODEL, EMPTY_CLASS_ARRAY);//通过反射获取getModel方法
Class cls = method.getReturnType();//获取getModel方法的返回值类型
cName = cls.getName();//获取model类名
} catch (NoSuchMethodException e) {//如果没有getModel方法则抛异常
throw new XWorkException("The " + GET_MODEL + "() is not defined in action " + action.getClass() + "", config);
}
}
String modelName = name;//model存储的key,初始值为null
if (modelName == null) {
modelName = cName;//把model的类名赋给model存储的key
}
Object model = resolveModel(objectFactory, ctx, cName, scope, modelName);//解析model
modelDriven.setModel(model);//把返回的model对象设置到Action中
modelDriven.setScopeKey(modelName);//返回model存储的key设置到Action中
}
}
return invocation.invoke();//调用下一个拦截器
}

该方法的逻辑还是挺简单的,如果Action的getModel方法返回不为null的话,strust2就不会去修改Action的model属性,这也更符合我们的应用
要求,不然这个拦截器就太"霸道"了,然后去解析获取model对象,最后把返回的model对象与model对象存储的key设置到Action中,现在去看一下
resolveModel方法:

protected Object resolveModel(ObjectFactory factory, ActionContext actionContext, String modelClassName, String modelScope, String modelName) throws Exception {
Object model = null;
Map<String, Object> scopeMap = actionContext.getContextMap();//获取ActionContext内容的context Map对象
if ("session".equals(modelScope)) {//如果配置了scope为session,但这里并没有配置
scopeMap = actionContext.getSession();//所以这里不会执行
} model = scopeMap.get(modelName);//去context Map(即相当于request作用域)中查找
if (model == null) {//没有找到
model = factory.buildBean(modelClassName, null);//调用对象工厂的buildBean方法实例化一个对象
scopeMap.put(modelName, model);//放置到context Map中
}
return model;//返回model对象
}

该方法先去作用域查找,如果查找不到再由ObjectFactory对象创建一个,ObjectFactory是struts2中专门用于创建对象的,其内部就是通过反射调用
class.newInstance()创建,sturst2中的Action、Result、Interceptor都是由ObjectFactory创建。model对象创建好后放入到了request作用域中,该方法执行完成后又把返回的model设置进了Action,如果Action对model进行了接收,那么Action中的model是有值的。

到这该拦截器就讲解完毕了,最后调用invocation.invoke();调用下一个拦截器

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

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

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

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

    ModelDrivenInterceptor 该拦截器处于defaultStack中的第九的位置,在ScopedModelDrivenInterceptor拦截器之后,要使该拦截器有效的话,Actio ...

  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. 【学习笔记】python2和python3的input()

    python2中的input()只接受变量作为传入值,非变量内容会报错. >>> user=input("Enter your name:") Enter you ...

  2. jquery开发表格插件项目之知识点累积 二

    $.addClass() 增加样式 $.removeClass() 去除样式 $.toggleClass() 单击增加样式,再单击取消样式 $.hasClass() 判断是否存在样式,存在返回true ...

  3. Atcoder Grand Contest 010 B - Boxes 差分

    B - Boxes 题目连接: http://agc010.contest.atcoder.jp/tasks/agc010_b Description There are N boxes arrang ...

  4. Codeforces Round #374 (Div. 2) A. One-dimensional Japanese Crosswor 水题

    A. One-dimensional Japanese Crossword 题目连接: http://codeforces.com/contest/721/problem/A Description ...

  5. c# RSA 加密解密 java.net公钥私钥转换 要解密的模块大于128字节

    有一个和接口对接的任务,对方使用的是java,我方使用的是c#,接口加密类型为RSA,公钥加密私钥解密. 然后就是解决各种问题. 1.转换对方的密钥字符串 由于c#里面需要使用的是xml各式的密钥字符 ...

  6. [Asp.net core]使用Polly网络请求异常重试

    摘要 在网络传输过程中,不能保证所有的请求都能正确的被服务端接受或者处理,那么进行简单的重试可以进行简单的补救.比如现在大部分支付功能,在支付成功之后,需要回调我们网站的接口,并且要求我们的接口给一个 ...

  7. .Net Discovery 系列之七--深入理解.Net垃圾收集机制(拾贝篇)

    关于.Net垃圾收集器(Garbage Collection),Aicken已经在“.Net Discovery 系列”文章中有2篇的涉及,这一篇文章是对上2篇文章的补充,关于“.Net Discov ...

  8. Fiddler抓包12-AutoResponder返回本地数据(mock)

    前言 mock可以说是面试必问的话题的,我第一次接触mock的时候也是一脸懵逼.虽然fiddler工具用了很久,里面的打断点,设置自动返回数据功能都用过. mock说的通俗一点就是模拟返回数据,只是面 ...

  9. 天蝎第一季/全集Scorpion迅雷下载

    英文译名 Scorpion (第1季) (2014-秋季播出)CBS.本季看点:<天蝎>双名蝎子故事描述一个高深莫测的计算机专家和一群同样具备天才头脑的国际计算机黑客共同组建全球防御网络, ...

  10. android之卸载反馈的功能

    感谢这位大神:http://www.eoeandroid.com/thread-317728-1-1.html zip包里面有讲解的试用方法,和如何试用ndk编译的方法,本人亲身试验,确实可用,现做一 ...