`

深入解析OGNL投影

    博客分类:
  • java
阅读更多

先看这个表达式:list.{#me=#this,#root.map[#me]}

 

这个表达式有这么几个点:

 

1. #this

 

在"投影"里#this指向的是list的子元素, 我想这个大家都知道,就不多说了

 

2. #root

 

在"投影"里如何访问"投影"外面的元素,这个问题困扰了我很长时间, 今天看了下OGNL的源代码, 原来用#root可以访问根元素,#context可以访问上下文里的元素,#this可以访问当前对象的元素;

 

在struts里,原本最开始当前对象就是根元素,但到"投影"里就把当前对象指向了投影的子元素了

 

相关OGNL源代码如下:

 

if (RESERVED_KEYS.containsKey(key)) {
            if (key.equals(OgnlContext.THIS_CONTEXT_KEY)) {
                result = getCurrentObject();
            } else {
                if (key.equals(OgnlContext.ROOT_CONTEXT_KEY)) {
                    result = getRoot();
                } else {
                    if (key.equals(OgnlContext.CONTEXT_CONTEXT_KEY)) {
                        result = this;
                    } else {
                        if (key.equals(OgnlContext.TRACE_EVALUATIONS_CONTEXT_KEY)) {
                            result = getTraceEvaluations() ? Boolean.TRUE : Boolean.FALSE;
                        } else {
                            if (key.equals(OgnlContext.LAST_EVALUATION_CONTEXT_KEY)) {
                                result = getLastEvaluation();
                            } else {
                                if (key.equals(OgnlContext.KEEP_LAST_EVALUATION_CONTEXT_KEY)) {
                                    result = getKeepLastEvaluation() ? Boolean.TRUE : Boolean.FALSE;
                                } else {
                                    if (key.equals(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY)) {
                                        result = getClassResolver();
                                    } else {
                                        if (key.equals(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY)) {
                                            result = getTypeConverter();
                                        } else {
                                            if (key.equals(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY)) {
                                                result = getMemberAccess();
                                            } else {
                                                throw new IllegalArgumentException("unknown reserved key '" + key + "'");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } else {
            result = values.get(key);
        }
 

 

3.  map[#me]

 

这样的写法和map.get(#me)的效果是一样, 但为什么不直接用#this呢? 原因在于4

 

4. #me=#this,

 

 为什么这么写? (逗号表达式就不解释了)

 

因为“投影”里面的context与外面的context是不同的,但“投影”里的方法使用的确是外面的context(这算不算是一个BUG.....),所以只好用一个普通变量作为引用,防止因为上下文不一样,造成第2点中给出的源代码解析成错误的值.

 

 

 

总结,

 

OGNL使用起来,还是很方便的.官方对其使用方法的文档写的也非常详细,但像作用域这样的"隐藏"概念确没多少资料,希望我的这篇文章能给大家提供一点帮助.

 

 

 


0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics