struts2 18拦截器详解(九) --- ScopedModelDrivenInterceptor

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();调用下一个拦截器

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值