1

Working with OGNL you can reference action context objects like #application, #session,#root, #action,#request,#parameters,#attr, and the action context with #context.

The framework sets the OGNL context to be our ActionContext, and the value stack to be the OGNL root object.

And OGNL uses [] as index reference to access an object properties. For example if the object foo has a property bar then it can access like foo.bar or foo['bar']. It also works if foo is a map and bar is a key.

Now, I want to put a variable and a value to the value stack context like that

<s:set var="bar" value="'hello'"/>
<s:set var="foo" value="'bar'"/>

and print the value

<s:property value="%{#attr[#foo]}"/>

It should print hello.

I'd like to know how this works. I know that #attr is an object that doesn't have a property referenced by #foo, i.e. bar. However this works. It also works if I use #request and #context, and probably #root instead of #attr. Neither of this objects has a property bar, but OGNL thinks otherwise. I'd like to know what OGNL thinks about property of the object it references and why this expression is working. Also if there are alternative ways to print hello using #foo reference in OGNL expression.

Roman C
  • 49,761
  • 33
  • 66
  • 176
  • Where the variables will be stored if `scope` isn't specified in `` tag? – Aleksandr M May 28 '14 at 18:40
  • It will store in the value stack context, I have mentioned it. – Roman C May 28 '14 at 18:43
  • Well not exactly. The value will be put into the value stack context map **and** will be set in the stack with the `#attr[var]` expression. – Aleksandr M May 28 '14 at 18:55
  • The value stack context is a map, with the expression I don't set but get the variable and then the value. – Roman C May 29 '14 at 07:00
  • What? Have you understood what set tag does? – Aleksandr M May 29 '14 at 08:18
  • Forget for the moment about more difficult case and try ``. Do you understand why it returns `bar`? – Aleksandr M May 29 '14 at 09:10
  • Yes, and I mentioned it in many of my answers, but you never, doesn't matter, I think I explained enough to understand what I want. I will also answer you questions if you have. Thanks for your time and effort. – Roman C May 29 '14 at 10:15
  • @AleksandrM Can you elaborate what `#attr.foo` is doing? Also with conjunction of what `#context` and `#request` are doing, and how it differs? – Roman C May 29 '14 at 10:31
  • 1
    The `#request.foo` gets request attribute with name `foo` from the request. The `#context.foo` gets value from OGNL context value map with key `foo`. And `#attr.foo` tries to get value from page context, then from the request, then from the session and then from application scope. – Aleksandr M May 29 '14 at 10:49
  • That's right, but it's not what I have asked. What will return the `#request.foo` if it doesn't have attribute with name `foo`? Why it returns `bar`? – Roman C May 29 '14 at 11:05
  • Because this is how S2 request wrapper is implemented, if request attribute isn't found then it gets value from the value stack. This is basics of Struts2. – Aleksandr M May 29 '14 at 11:23
  • @AleksandrM Request wrapper is different object, `#request` refers to request map. How it gets or not gets the value from the value stack is a question I asked. I want the explanation. – Roman C May 29 '14 at 11:29
  • And where from request map will get its values? :) – Aleksandr M May 29 '14 at 11:33
  • @AleksandrM Well, now I think it's different story for each objects that works. Request map is getting values from request wrapper, don't know why, it should already have all request attributes. – Roman C May 29 '14 at 12:11

1 Answers1

2

In the given expression <s:property value="#attr[#foo]"/> the part inside [] will be evaluated first. The #foo is resolved to bar so expression becomes #attr['bar'] (which is equivalent to #attr.bar).

Using #attr.bar the value for bar will be searched until it is found in the page context, then in the request, then in the session and then in the application scope.

The #context.bar gets value from OGNL context value map with key bar.

The #request.bar tries to get request attribute with name bar from the request map and if it isn't found then bar will be searched in the value stack. This happens in Struts2 request wrapper implementation.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Aleksandr M
  • 24,264
  • 12
  • 69
  • 143
  • Can you check [this](http://stackoverflow.com/questions/26067412/struts2-jsp-el-concatenation-doesnt-seem-to-work) one? I have a similar problem. – Kevin Rave Sep 26 '14 at 20:29