This week's book giveaway is in the Mac OS forum.
We're giving away four copies of a choice of "Take Control of Upgrading to Yosemite" or "Take Control of Automating Your Mac" and have Joe Kissell on-line!
See this thread for details.
The moose likes Struts and the fly likes Struts 2: %{} or # Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Frameworks » Struts
Bookmark "Struts 2: %{} or #" Watch "Struts 2: %{} or #" New topic
Author

Struts 2: %{} or #

Vu Pham
Ranch Hand

Joined: May 28, 2005
Posts: 100
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 :-)
Sonny Gill
Ranch Hand

Joined: Feb 02, 2002
Posts: 1211

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


The future is here. It's just not evenly distributed yet. - William Gibson
Consultant @ Xebia. Sonny Gill Tweets
Vu Pham
Ranch Hand

Joined: May 28, 2005
Posts: 100
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()?
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

Because it's looking for a resource (message) under the key "response", not calling getResponse().
Victor Hou
Greenhorn

Joined: Dec 16, 2008
Posts: 4
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!


Just knowing<br /> <br />I am start Learning English now.
Vu Pham
Ranch Hand

Joined: May 28, 2005
Posts: 100
Ok, thanks Sony and David :-)
Vu Pham
Ranch Hand

Joined: May 28, 2005
Posts: 100
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

Joined: Dec 16, 2008
Posts: 4
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

Joined: Feb 02, 2002
Posts: 1211

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

Joined: Dec 16, 2008
Posts: 4
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.
Sailesh Ganeshan
Greenhorn

Joined: Sep 29, 2010
Posts: 13
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>


Live your life. Don't just exist.
 
GeeCON Prague 2014
 
subject: Struts 2: %{} or #