Struts2(9)——struts2与OGNL的结合(二)

来源:互联网 发布:手机vpn代理软件 编辑:程序博客网 时间:2024/06/05 08:13

前面几篇笔记中,我们在jsp页面中向Action传递了参数,通过这样三种方式:
1.属性驱动
将参数作为Action的一个属性
2.对象驱动
将实体类作为Action的属性
3.模型驱动
Action实现ModelDriven接口;实体类作为私有变量并实例化;实现getModel()方法,并返回实体对象。

现在探究一下原理:
关于1、2两种方式,我们在上一篇中谈论过,OgnlValueStack的Root中存储有当前action,那么,按照Ognl表达式的语法,”name=’xxx’”的语义即为将xxx赋值给Action的name属性,同理,”user.name=’xxx’”即赋值给Action的user属性的name属性。
但模型驱动的方式其原理则稍微复杂一些。已知的是root是一个栈结构,所以理论上要为user对象赋值,需要将其压入栈中,使其处在栈顶位置。
我们知道在数据提交到Action的过程中将会经过二十个拦截器,这些拦截器中有一个拦截器,负责将数据赋值给对象,该拦截器可以在struts.default.xml中看到,标签为<params>,而赋值需要在将对象压入值栈之后进行。这时就需要<prepare/>拦截器发挥作用,该拦截器执行顺序在action.excute之前,用以对action进行准备操作。查看源码,所在包:package com.opensymphony.xwork2.interceptor;

核心源码如下:

public String doIntercept(ActionInvocation invocation) throws Exception {//获取当前操作的Action        Object action = invocation.getAction();        //判断是否为Prepareable接口实现对象        if (action instanceof Preparable) {            try {                String[] prefixes;                if (this.firstCallPrepareDo) {                    prefixes = new String[]{"prepareDo", "prepare"};                } else {                    prefixes = new String[]{"prepare", "prepareDo"};                }//反射方式为其实现该接口                PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);            } catch (InvocationTargetException var5) {                Throwable cause = var5.getCause();                if (cause instanceof Exception) {                    throw (Exception)cause;                }                if (cause instanceof Error) {                    throw (Error)cause;                }                throw var5;            }            if (this.alwaysInvokePrepare) {                ((Preparable)action).prepare();            }        }        return invocation.invoke();    }

这样,我们就能够在赋值前,将其先进行入栈操作。
那么实现ModelDriven接口就可以为属性赋值就变得很好解释了,在struts-default.xml中,我们可以看到modelDriven这个拦截器的顺序是在param之前的,而在其源码之中,还能看到它将action中的对象压入了值栈。

阅读全文
0 0