struts2值栈取值从源代码中分析

来源:互联网 发布:mac版photoshop快捷键 编辑:程序博客网 时间:2024/06/06 23:02

想要知道struts2取值原理 就从源码中看struts2的拦截器顺序知道原理

从struts2-core\2.3.24\struts2-core-2.3.24.jar核心包里面找到的核心配置文件 struts-default.xml

 <interceptor-stack name="defaultStack">                <interceptor-ref name="exception"/>                <interceptor-ref name="alias"/>                <interceptor-ref name="servletConfig"/>                <interceptor-ref name="i18n"/>                <interceptor-ref name="prepare"/>                <interceptor-ref name="chain"/>                <interceptor-ref name="scopedModelDriven"/>                <interceptor-ref name="modelDriven"/>                <interceptor-ref name="fileUpload"/>                <interceptor-ref name="checkbox"/>                <interceptor-ref name="datetime"/>                <interceptor-ref name="multiselect"/>                <interceptor-ref name="staticParams"/>                <interceptor-ref name="actionMappingParams"/>                <!--这个是参数拦截器params -->                <interceptor-ref name="params"/>                <interceptor-ref name="conversionError"/>                <interceptor-ref name="validation">                    <param name="excludeMethods">input,back,cancel,browse</param>                </interceptor-ref>

找到params实现类

 <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

这是实现类

public class ParametersInterceptor extends MethodFilterInterceptor

从实现类里面找到doIntercept(拦截器核心方法)

  public String doIntercept(ActionInvocation invocation) throws Exception {          //获取当前action        Object action = invocation.getAction();        //如果action没有实现NoParameters就不会进去,        /*        假设我if条件为true进去了        */        if (!(action instanceof NoParameters)) {        //获取action上下文            ActionContext ac = invocation.getInvocationContext();            final Map<String, Object> parameters = retrieveParameters(ac);            if (LOG.isDebugEnabled()) {                LOG.debug("Setting params " + getParameterLogMap(parameters));            }            if (parameters != null) {                Map<String, Object> contextMap = ac.getContextMap();                try {                    ReflectionContextState.setCreatingNullObjects(contextMap, true);                    ReflectionContextState.setDenyMethodExecution(contextMap, true);                    ReflectionContextState.setReportingConversionErrors(contextMap, true);                    //通过action上下问去值,下面看getValueStack()                    //是怎么实现的                    ValueStack stack = ac.getValueStack();                    setParameters(action, stack, parameters);                } finally {                    ReflectionContextState.setCreatingNullObjects(contextMap, false);                    ReflectionContextState.setDenyMethodExecution(contextMap, false);                    ReflectionContextState.setReportingConversionErrors(contextMap, false);                }            }        }        return invocation.invoke();    }
    //这是ActionContext类下的方法   public ValueStack getValueStack() {        return (ValueStack) get(VALUE_STACK);    }    //找到这个常亮在跟这找     public static final String VALUE_STACK = ValueStack.VALUE_STACK;
public interface ValueStack {    //就找到这里了ValueStack 是个接口看实现类    public static final String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack";
//看类名知道了取值是用的OGNL表达式取的值public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack {  //...这里不是关键代码就删掉了      //这是struts2的值栈 现在看struts2是怎么实现栈结构的      //栈结构肯定有压栈,和弹栈两个方法    CompoundRoot root;       //这是struts2 context    transient Map<String, Object> context;
//值栈用的是ArrayList 集合,在看看压栈和弹栈两个方法public class CompoundRoot extends ArrayList {    public CompoundRoot() {    }    public CompoundRoot(List list) {        super(list);    }    public CompoundRoot cutStack(int index) {        return new CompoundRoot(subList(index, size()));    }    public Object peek() {        return get(0);    }    //弹栈    /**    每次都是从第0号元素删除,遵守了栈规则    */    public Object pop() {        return remove(0);    }    //压栈    /**        栈规则是:前进后出        每一次添加都要ArrayList集合中的第0个元素开始,        是栈结构    */    public void push(Object o) {        add(0, o);    }}
  • 上面写了,知道了struts2的赋值的原理所以我们想让struts自动赋值一定要在 params 拦截器之前赋值。下面我们在回到struts2拦截器上
<interceptor-stack name="defaultStack">                <interceptor-ref name="exception"/>                <interceptor-ref name="alias"/>                <interceptor-ref name="servletConfig"/>                <interceptor-ref name="i18n"/>                <!--是在params拦截器之上可用这个拦截器                进行赋值                <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>                -->                <interceptor-ref name="prepare"/>                <interceptor-ref name="chain"/>                <interceptor-ref name="scopedModelDriven"/>                <!--这个是模型驱动 这就是模型驱动可以赋值的原因modelDriven拦截器是在params拦截器上面-->                <interceptor-ref name="modelDriven"/>                <interceptor-ref name="fileUpload"/>                <interceptor-ref name="checkbox"/>                <interceptor-ref name="datetime"/>                <interceptor-ref name="multiselect"/>                <interceptor-ref name="staticParams"/>                <interceptor-ref name="actionMappingParams"/>                <interceptor-ref name="params"/>                <interceptor-ref name="conversionError"/>                <interceptor-ref name="validation">                    <param name="excludeMethods">input,back,cancel,browse</param>                </interceptor-ref>                <interceptor-ref name="workflow">                    <param name="excludeMethods">input,back,cancel,browse</param>                </interceptor-ref>                <interceptor-ref name="debugging"/>                <interceptor-ref name="deprecation"/>            </interceptor-stack>
  • prepare拦截器赋值使用
    (模板驱动就不写了,我相信大家都会写)
//实现Preparable接口添加未实现方法prepare()public class Dome1 extends ActionSupport implements Preparable {    private User user = new User();    //实现原理把要赋值的对象压入栈顶    @Override    public void prepare() throws Exception {        //1获得值栈        ValueStack vs = ActionContext.getContext().getValueStack();        //2将u压入栈顶        vs.push(user);    }}
阅读全文
1 0
原创粉丝点击