Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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:

Code Block
nonenone
#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...

Info
titleUseful 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.

For example, suppose the stack contains two objects: Animal and Person. Both objects have a "name" property, Animal has a "species" property, and Person has a "salary" property. Animal is on the top of the stack, and Person is below it. The follow code fragments help you get an idea of what is going on here:

Code Block
nonenone
species    // call to animal.getSpecies()
salary     // call to person.getSalary()
name       // call to animal.getName() because animal is on the top

In the last example, there was a tie and so the animal's name was returned. Usually this is the desired effect, but sometimes you want the property of a lower-level object. To do this, XWork has added support for indexes on the ValueStack. All you have to do is:

none
Code Block
none
[0].name   // call to animal.getName()
[1].name   // call to person.getName()

...

ognl expression

description

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="74f1c224d79d28c7-bff9645a-4ce24ff7-83cebcdf-a128b559a48beebddd1f2329"><ac:plain-text-body><![CDATA[

[0].top

would get the top of the stack cut starting from element 0 in the stack (similar to top in this case)

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="3b4ad22cdbdbf8e8-da9f1a6d-43ec4686-a6ada31f-73309f6e3cd6670b03e18a55"><ac:plain-text-body><![CDATA[

[1].top

would get the top of the stack cut starting from element 1 in the stack]]></ac:plain-text-body></ac:structured-macro>

...

However, XWork allows you to avoid having to specify the full package name and call static properties and methods of your action classes using the "vs" prefix:

Code Block
nonenone
<at:var at:name="vs" />FOO_PROPERTY
<at:var at:name="vs" />someMethod()

<at:var at:name="vs1" />FOO_PROPERTY
<at:var at:name="vs1" />someMethod()

<at:var at:name="vs2" />BAR_PROPERTY
<at:var at:name="vs2" />someOtherMethod()

...

Old Expression

New Expression

foo/blah

foo.blah

foo/someMethod()

foo.someMethod()

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a2594da4ee8d3683-b507241a-43144a2e-80a4a640-7c05f8253088047283344f91"><ac:plain-text-body><![CDATA[

../bar/blah

[1].bar.blah

]]></ac:plain-text-body></ac:structured-macro>

@baz

not directly supported, but #baz is similar

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="6445935151ac8736-754d7bce-4a8f41a6-9c809a0e-ed896817362d3645373cb1a7"><ac:plain-text-body><![CDATA[

.

top or [0]

]]></ac:plain-text-body></ac:structured-macro>

...

name

value

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="90fd7fb65978327c-cc4e7ef6-48644c30-98fc837d-ef20e99801f6897cd9b16ca0"><ac:plain-text-body><![CDATA[

#parameters['foo'] or #parameters.foo

request parameter ['foo'] (request.getParameter())

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="9b3368f57e2e61a3-ed14c226-43b64f89-8f16992c-7239668fd59b69e7c49f8e7a"><ac:plain-text-body><![CDATA[

#request['foo'] or #request.foo

request attribute ['foo'] (request.getAttribute())

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="ce0c773bda1d904b-f6e516fd-4c1c4b64-965e9285-752978d5cb6037ce2b09f2c1"><ac:plain-text-body><![CDATA[

#session['foo'] or #session.foo

session attribute 'foo'

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="27bdd9238a7f9ead-ce4fe065-48814a7f-9c34a5f6-61e519c61300860675c87bb2"><ac:plain-text-body><![CDATA[

#application['foo'] or #application.foo

ServletContext attributes 'foo'

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="387d8c94f52b42f8-790cf921-49ac4d91-9c2b80cb-03abb5a90cf2041aa3ece780"><ac:plain-text-body><![CDATA[

#attr['foo'] or #attr.foo

Access to PageContext if available, otherwise searches request/session/application respectively

]]></ac:plain-text-body></ac:structured-macro>