Struts2 Tag & EL & OGNL

为什么使用表达式语言(EL)
表达式语言(EL)本质上被设计为:帮助你使用简单的表达式来完成一些“常用”的工作。通常情况下,ELs 可以在一些框架中找到,它被是用来简化我们的工作。例如:大家熟知的 Hibernate,使用 HQL(Hibernate Query Language) 来完成数据库的操作,HQL 成了开发人员与复查的 SQL 表达式之间的一个桥梁。 在 web 框架下,表达式语言起到了相似的目的。它的存在消除了重复代码的书写。

在Struts2标签里已经不能使用EL表达式,如果在Struts标签里使用EL表达式,会提示"value" does not support run-time expressions。具体原因是从Struts2.0.10以后,Struts2 标签已经禁用EL表达式了。

Release Notes 2.0.10: 

Struts 2.0.10 corrects a serious security flaw in the Struts 2 tags where using JSP EL expressions could allow malicious OGNL expressions through. All users are encouraged to update to Struts 2.0.10. Note that existing pages that utilize JSP EL expressions with Struts 2 tags will no longer work as of this release.

原因是支持EL表达式会导致允许恶意的OGNL表达式执行,果断禁用。

XWork-specific language features——OGNL

The biggest addition that XWork provides on top of OGNL is the support for the ValueStack. While OGNL operates under the assumption there is only one "root", XWork's ValueStack concept requires there be many "roots".

For example, suppose we are using standard OGNL (not using XWork) and there are two objects in the OgnlContext map: "foo" -> foo and "bar" -> bar and that the foo object is also configured to be the single root object. The following code illustrates how OGNL deals with these three situations:

#foo.blah // returns foo.getBlah()
#bar.blah // returns bar.getBlah()
blah      // returns foo.getBlah() because foo is the root

What this means is that OGNL allows many objects in the context, but unless the object you are trying to access is the root, it must be prepended with a namespaces such as @bar. Now let's talk about how XWork is a little different...

Useful Information
In XWork, the entire ValueStack is the root object in the context. Rather than having your expressions get the object you want from the stack and then get properties from that (ie: peek().blah), XWork has a special OGNL PropertyAccessor that will automatically look at the all entries in the stack (from the top down) until it finds an object with the property you are looking for.

The framework uses a standard naming context to evaluate OGNL expressions. The top level object dealing with OGNL is a Map (usually referred as a context map or context). OGNL has a notion of there being a root (or default) object within the context. In expression, the properties of the root object can be referenced without any special "marker" notion. References to other objects are marked with a pound sign (#).

The framework sets the OGNL context to be our ActionContext, and the value stack to be the OGNL root object. (The value stack is a set of several objects, but to OGNL it appears to be a single object.) Along with the value stack, the framework places other objects in the ActionContext, including Maps representing the application, session, and request contexts. These objects coexist in the ActionContext, alongside the value stack (our OGNL root).

The Action instance is always pushed onto the value stack. Because the Action is on the stack, and the stack is the OGNL root, references to Action properties can omit the #marker. But, to access other objects in the ActionContext, we must use the # notation so OGNL knows not to look in the root object, but for some other object in the ActionContext.

ActionContext & OGNL value stack

                     |
                     |--application
                     |
                     |--session
       context map---|
                     |--value stack(root)
                     |
                     |--request
                     |
                     |--parameters
                     |
                     |--attr (searches page, request, session, then application scopes)
                     |


OGNL相关的文章:
Struts2官方-OGNL
忘记李刚,一步一步跟我学Struts2 —— OGNL,数据运转的催化剂
OGNL 语言介绍与实践
Struts 2.0 的OGNL 组件
Struts2 内核之我见
posted @ 2012-05-03 22:13  cuillgln  阅读(380)  评论(0编辑  收藏  举报