`

struts2对Ognl的封装--root对象

 
阅读更多

 

root 对象  

     CompoundRoot, CompoundRoot扩展了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);
    }

    public Object pop() {
        return remove(0);
    }

    public void push(Object o) {
        add(0, o);
    }
}

(不明白为啥用0做栈顶呢?ArrayList 每次push 或remove 之后都需要重建数组)

 

CompoundRoot中元素的添加及提取:

OgnlValueStack提供的peek,pop,push 方法,从root中提取元素或添加元素: 

Java代码 
  1. /** 
  2.  * @see com.opensymphony.xwork2.util.ValueStack#peek() 
  3.  */  
  4. public Object peek() {  
  5.     return root.peek();  
  6. }  
  7.   
  8. /** 
  9.  * @see com.opensymphony.xwork2.util.ValueStack#pop() 
  10.  */  
  11. public Object pop() {  
  12.     return root.pop();  
  13. }  
  14.   
  15. /** 
  16.  * @see com.opensymphony.xwork2.util.ValueStack#push(java.lang.Object) 
  17.  */  
  18. public void push(Object o) {  
  19.     root.push(o);  
  20. }  

  

通过表达式对CompoundRoot中元素的访问

 

CompoundRootAccessor 实现了 CompoundRoot 中元素以表达式方式的访问,

CompoundRootAccessor类扩展了ognl的PropertyAccessor,MethodAccessor,ClassResolver

 



Ognl中的root对象一般是一个javabean或Map,通过表达式中指定的属性名或key,就可以定位到属性对象

 CompoundRoot 是一个ArrayList,对于表达式中指定的属性,是ArrayList中哪一个元素的属性呢? 这就需要遍历每一个元素,进行判断。

 

  

以表达式方式对CompoundRoot  中元素的属性赋值(setProperty):

  对 CompoundRoot  遍历遍历顺序由栈顶到栈底,遍历的每一个元素,都当做ognl的root对象,判断是否存在指定的属性,如果存在则对该root对象的属性赋值,遍历中下一个元素是Map,则直接使用put 方法存属性和名称,就不继续查找了:

        for (Object o : root) {//CompoudRoot是ArrayList,遍历内部所有对象
            if (o == null) {
                continue;
            }

            try {
                if (OgnlRuntime.hasSetProperty(ognlContext, o, name)) {
                    OgnlRuntime.setProperty(ognlContext, o, name, value);
                    //当前元素有name属性,则调用ognl进行赋值
                    return;
                } else if (o instanceof Map) {
                    Map<Object, Object> map = (Map) o;
                    try {
                        map.put(name, value);
                        return;//如果下一个元素是Map,则直接使用put方法存属性名和值
                    } catch (UnsupportedOperationException e) {
                        // This is an unmodifiable Map, so move on to the next element in the stack
                    }
                }
}

  

以表达式方式对CompoundRoot  中元素的属性值的获值(getProperty):

  对 CompoundRoot  遍历遍历顺序由栈顶到栈底,遍历的每一个元素,都当做ognl的root对象,判断是否存在指定的属性,如果存在则获值属性值:

 

            for (Object o : root) {//遍历
                if (o == null) {
                    continue;
                }

                try {
                    if ((OgnlRuntime.hasGetProperty(ognlContext, o, name)) || ((o instanceof Map) && ((Map) o).containsKey(name))) {
                        return OgnlRuntime.getProperty(ognlContext, o, name);//当前元素有该属性,则获取
                    }
                } catch (OgnlException e) {
                    if (e.getReason() != null) {
                        final String msg = "Caught an Ognl exception while getting property " + name;
                        throw new XWorkException(msg, e);
                    }
                } catch (IntrospectionException e) {
                    // this is OK if this happens, we'll just keep trying the next
                }
            }

 

以表达式方式对CompoundRoot  中元素的方法调用(callMethod):

  对 CompoundRoot  遍历遍历顺序由栈顶到栈底,遍历的每一个元素,都当做ognl的root对象,对其调用指定的方法,如果返回值不为空,则说明正确,并返回方法返回值。

 

 

        for (Object o : root) {//遍历
            if (o == null) {
                continue;
            }

            Class clazz = o.getClass();
            Class[] argTypes = getArgTypes(objects);

            MethodCall mc = null;

            if (argTypes != null) {
                mc = new MethodCall(clazz, name, argTypes);
            }

            if ((argTypes == null) || !invalidMethods.containsKey(mc)) {
                try {
                    Object value = OgnlRuntime.callMethod((OgnlContext) context, o, name, name, objects);

                    if (value != null) {//返回值不为空,该元素上有此方法并调用成功
                        return value;
                    }
                } catch (OgnlException e) {
                    // try the next one
                    Throwable reason = e.getReason();

                    if (!context.containsKey(OgnlValueStack.THROW_EXCEPTION_ON_FAILURE) && (mc != null) && (reason != null) && (reason.getClass() == NoSuchMethodException.class)) {
                        invalidMethods.put(mc, Boolean.TRUE);
                    } else if (reason != null) {
                        throw new MethodFailedException(o, name, e.getReason());
                    }
                }
            }
        }

 

对 CompoundRoot    指定位置元素的访问:

1.top.属性名 (top 栈顶元素)

2.[index].top  CompoundRoot    中的第N个元素[index]会调用 CompoundRoot.cutStack从第indedx位置开始的元素组成新的 CompoundRoot,top是栈顶元素

 

分享到:
评论

相关推荐

    struts2标签和OGNL表达式

    使用OGNL表达式的一个关键原因是Struts2对HttpServletRequest进行了封装,创建了StrutsRequestWrapper类,这允许OGNL在不直接操作原始HTTP请求对象的情况下,仍能访问请求参数和其他特性,提高了代码的简洁性和可...

    ognl表达式 ognl表达式

    ### OGNL表达式的理解和应用 ...通过上述介绍可以看出,OGNL作为一种强大的表达式语言,在Struts2框架中扮演着非常重要的角色,不仅可以方便地访问和操作对象属性,还能有效地处理复杂的业务逻辑。

    Struts2的结构和编写过程笔记

    4. **配置过滤器**:编辑`/Webroot/WEB-INF/web.xml`文件,添加Struts2的过滤器配置。 ```xml &lt;filter-name&gt;struts2&lt;/filter-name&gt; &lt;filter-class&gt;org.apache.struts2.dispatcher.FilterDispatcher&lt;/filter-...

    Struts2文档教程

    - Struts2除了支持JSTL外,还内置了一个更加强大和灵活的表达式语言——OGNL,这使得数据操作更加简便。 #### 四、Struts2的优越性 - **开发前景**: Struts2是由Struts1和WebWork框架的开发团队共同开发的,具有...

    struts 2 源码 导入eclipse工程

    6. **Ognl(Object-Graph Navigation Language)**:Struts 2使用Ognl作为默认表达式语言,用于在Action与视图之间传递数据。 7. **Plug-in体系结构**:Struts 2支持插件化开发,通过StrutsPrepareAndExecuteFilter...

    Struts2 Ongl文档

    根据提供的文件信息,我们可以归纳出以下关于Struts2中OGNL(Object-Graph Navigation Language)的知识点: ### 1. 引言与简介 OGNL 是一种强大的表达式语言,它允许开发人员通过简洁的语法来导航 Java 对象。...

    struts2连接mysql多表查询

    例如,你可以创建一个`Employee`类来封装查询结果,然后将`List&lt;Employee&gt;`对象放入`ValueStack`,在JSP中使用OGNL表达式访问并展示数据。 以上就是使用Struts2连接MySQL并进行多表查询的基本步骤和关键知识点。...

    struts2下的分页浏览

    Struts2的核心是ValueStack,它是OGNL(Object-Graph Navigation Language)表达式语言的数据上下文。在这个项目中,分页相关的数据(如总页数、当前页数据列表等)会被放入ValueStack,然后在JSP页面上通过OGNL...

    struts2.1.8.1+jquery1.4.2返回json数据.pdf

    - **ognl-2.7.3.jar**:对象图导航语言,用于访问和修改对象图。 - **freemarker-2.3.15.jar**:模板引擎,用于页面渲染。 - **commons-fileupload-1.2.1.jar**:文件上传组件。 - **commons-io-1.3.2.jar**:提供了...

    ibatis 一个简单的项目详解

    实体Bean是ibatis与数据库交互的核心对象,用于封装数据。例如,这里定义了`Student`、`User`和`Page`三个实体Bean。 - **Student.java** ```java package com.vstsoft.model; import java.io.Serializable; ...

Global site tag (gtag.js) - Google Analytics