• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Struts 2: %{} or #

 
Ranch Hand
Posts: 100
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,

1. I'm confuse about %{variable} and #variable. What are the different between them?


2. I have 1 more question
In my project, I use

<s:text name="%{response}"/>

It can get the value from getResponse(), I can't use <s:text name="response"/>

However, in the same form, I use

<s:textarea rows="4" name="remarks" id="remarks" cols="100" />

It can get the value from getRemarks()

Do you know why?


Thanks :-)
 
Ranch Hand
Posts: 1211
Mac IntelliJ IDE
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
AFAIK..

%{variable} and #variable

Ok.. in Struts tags, whenever you enter a value for an attribute, it can either be treated as a literal value or it can be treated as an expression that is evaluated against the current value stack.

%{} syntax is used to force OGNL evaluation where Struts would otherwise be treating the value as a String literal.

For example,
<s:property value="name" />
will look for a name property in the value stack i.e. is a value retrieved by calling getName().
If you wanted to force it to use literal value "name", you will need to use the %{} syntax -
<s:property value="%{'name'}" />

#variable is used to refer to a variable that does not exist on the value stack, but rather exists somewhere else on the action context. This could be variables created by using the <set> tag, or values in session scope etc.


For your second question -
<s:textarea> tries to use the value of name attribute to get the same property from the value stack, so it gets the value from getRemarks(). No surprise there.
Normally <s:text> expects the name to be a key to be looked up in a resource bundle, so it can't get the value from getResponse() method.
If <s:text name="%{response}"/> is getting the value from getResponse(), then my guess is that this is because of forced OGNL evaluation as I explained earlier.


Struts 2 In Action book covers these concepts in a fair bit of detail. Or search online for "Struts 2 Value Stack", you should be able to find web pages or mailing list posts that explain these concepts in more detail.

Cheers,
Sonny
 
Vu Pham
Ranch Hand
Posts: 100
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sonny,

In my 2nd question, I used

<s:text name="response"/>

This one will be incorrect. Why it doesn't get the value from getResponse()?
 
Author
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Because it's looking for a resource (message) under the key "response", not calling getResponse().
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
honestly I didnt quite get the second question.
you mean different tags may save in different stack? but I thought all the parameters you defined in the Action would be save at value stack which means you can use the parameter without #. Am I right?
Another way to help you out, use the

Still I have a question for my own, hope any one could help me here is the code:

notice this wont work but if I change it to this code will go well.
Thanks in advance!
 
Vu Pham
Ranch Hand
Posts: 100
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, thanks Sony and David :-)
 
Vu Pham
Ranch Hand
Posts: 100
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Victor,

As I know, sometimes we can't use #variable, we must use %{#variable}. But I don't know why? Anyone know about this?
 
Victor Hou
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I got these sentences:
All String attribute types are parsed for the %{ ... } characters.
All non-String attribute types are not parsed, but instead evaluated directly as an OGNL expression
The exception to rule #2 is that if the non-String attribute starts with %{ and ends with }, those characters are cut off before evaluating the expression.
from:http://wiki.opensymphony.com/display/WW/Tag+Syntax
Now I doubt these from every problems I have faced.

It seems you may not use %{} to parse OGNL Expression only in this tag

and others if you wannar use OGNL Expression you should put it into the brace.
 
Sonny Gill
Ranch Hand
Posts: 1211
Mac IntelliJ IDE
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Victor Hou:

Still I have a question for my own, hope any one could help me here is the code:

notice this wont work but if I change it to this code will go well.



Because s:hidden expects the value to be a String literal by default i.e. if the value is "abc" it will try to call getAbc(). In this case, you dont' want "#st.index" to be treated as a String literal. Rather, you want to force Struts to treat it as an OGNL expression. That is why you need the %{} around it.
 
Victor Hou
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think I now fully understand
The second question

<s:text name="%{response}"/>

It can get the value from getResponse(), I can't use <s:text name="response"/>



If you read the source code "text.ftl" from template.simple of struts2-core* you will understand.
Look these codes below


See? the property of name is using a freemarker expression ${}, this will output a literl string, so you can just use the sring which you wannar to output. But if you wannar get a value from a parameter you should add %{} then struts will see it as an OGNL expression and this will be parsed as


Futher, I checked most of the tags in package of template.simple(which we always use in the project), I found only the value property of tag is calling a struts tag(@s.property value="parameters.nameValue"), that means it will do exactly as what Sonny said

<s:property value="name" />
will look for a name property in the value stack i.e. is a value retrieved by calling getName().
If you wanted to force it to use literal value "name", you will need to use the %{} syntax -
<s:property value="%{'name'}" />



Thanks Sonny and I must confess I didnt read your post carefully, plus,
here s:property value="%{'name'} why did you add '' around name? It's not a nessersary , I think.

P.S. I am not a native English speaker, so hope you can get what I mean.
 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys,

I'm using <s:property> default attribute. But, I cant use EL here,

please suggest a solution for this.

eg:

<s:property value="#itnObjl" default="%{testVar}"/>
I've tried this too : %{#testVar}

Where testVar is an <s:set>
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic