OGNL is the Object Graph Navigation Language (see http://www.ognl.org/
for the full documentation of OGNL). Here, we will cover a few examples
of OGNL features that co-exist with the framework. To review basic
concepts, refer to OGNL Basics.
OGNL是对象图形定位语言.这里将设计一个OGNL和框架并存的例子。
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 (#).
框架用一个标准命名上下文来计算OGNL表达式。处理OGNL的高层对象是Map。OGNL在上下文内有个根的概念。在表达式里,不需要任何“标志”关联到根对象的属性。关联到其他对象得用#标识。
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).
框架设置OGNLcontext为我们的 ActionContext, value stack 是OGNL根对象。(value stack是一系列的值,但对OGNL,它表现为一个对象)连同value stack,框架放置其他对象到ActionContext,包括展示application,session和request上下文。这些对象与value stack一起共存在ActionContext。
There are other objects in the context map. The diagram is for example only.
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.
Action 实例被推入value stack。因为Action在stack里,并且statck是OGNL的根,和Action关联的属性忽略#标记。但访问ActionContext的其他对象,我们必须用#标识,OGNL知道不应该区根对象查找,而是到ActionCopntext的其他对象里查找。
<s:property value="postalCode"/>
Other (non-root) objects in the ActionContext can be rendered use the # notation.
<s:property value="#session.mySessionPropKey"/> or
<s:property value="#session["mySessionPropKey"]"/> or
<s:property value="#request["mySessionPropKey"]/>
The ActionContext is also exposed to Action classes via a static method.
ActionContext也通过静态方法被暴露给Action类
ActionContext.getContext().getSession().put("mySessionPropKey", mySessionObject);
Collections (Maps, Lists, Sets)
Dealing with Collections (Maps, Lists, and Sets) in the framework comes often, so here are a few examples using the select tag.
声明集合在框架中经常用到,所以这里是用select标签的例子。
Syntax for list: {e1,e2,e3}. This idiom creates a List containing
the String "name1", "name2" and "name3". It also selects "name2" as the
default value.
list语法:{e1,e2,e3}.这个习惯创建一个包括“name1”,“name2”和“name3”。它也选择“name2”作为默认值。
<s:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}" />
Syntax for map: #{key1:value1,key2:value2}. This idiom creates a map
that maps the string "foo" to the string "foovalue" and "bar" to the
string "barvalue":
map语法:#{key1:value1,key2:value2}.这个创建map,把字符传“foo”到字符串"foovalue",“bar”到字符串"barvalue".
<s:select label="label" name="name" list="#{'foo':'foovalue', 'bar':'barvalue'}" />
To determine if an element exists in a Collection, use the operations in and not in.
用in 和 not in 检验元素是否在一个集合里面
<s:if test="'foo' in {'foo','bar'}">
muhahaha
</s:if>
<s:else>
boo
</s:else>
<s:if test="'foo' not in {'foo','bar'}">
muhahaha
</s:if>
<s:else>
boo
</s:else>
To select a subset of a collection (called projection), use a wildcard within the collection.
- ? - All elements matching the selection logic
- ^ - Only the first element matching the selection logic
- $ - Only the last element matching the selection logic
To obtain a subset of just male relatives from the object person:
person.relatives.{? #this.gender == 'male'}
OGNL supports basic lamba expression syntax enabling you to write simple functions.
(Dedicated to all you math majors who didn't think you would ever see this one again.)
Fibonacci: if n==0 return 0; elseif n==1 return 1; else return fib(n-2)+fib(n-1);
fib(0) = 0
fib(1) = 1
fib(11) = 89
|
How the expression works
The lambda expression is everything inside the brackets. The #this
variable holds the argument to the expression, which is initially
starts at 11.
|
<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />
JSP 2.1
Under JSP 2.1 the # character is now used by the JSP EL.
This may cause problems with some applications that use the OGNL # operator.
One quick-fix is to disable the JSP EL in a JSP 2.1 container (like GlassFish) by adding a jsp-config element to the web.xml
和JSP2.1的兼容问题处理
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>