Struggling with the <s:action .. /> tag
Thanks to the comment left by Philip Luppens I have since taken another look at this tag and found a better way to do things. The entry below has been modified to reflect that improved method. I found that method here:
http://www.nabble.com/Re%3A--S2--s%3Aaction-in-value-stack--p21764311.html
I found this to be another doozey, certainly it was partly my fault as I didn't read the Struts2 documentation on this tag very well. The problem was there was only a very short description so I skipped to the examples as I thought they would be more informative. Unfortunatly the example is also misleading and a better way exists.
Anyway, this tag acts as a way to include the result of an action in your JSP. Think of it like this (although it doesn't work this way):
<jsp:include page='/mynamespace/myaction.action' />
Ok, so how do you use this tag, firstly here are the caveats about its use. Once you have these in your head your life will become easier:
- This tag NEVER goes onto the value stack! This may not be strictly accurate but thinking of it this way is useful. When you are within the body of the tag it is NOT possible to reference it in the normal way. You can apparently use the value="top.myProperty" method (the keyword here is top which references the item on the top of the stack, but I couldn't get this to work as I found the original action was always on top. The original action being the one that forwarded to the JSP page with the <s:action ... /> tag in it. The reason you can't access it in the normal way is that the tag does not get an id or var value until AFTER the tag is closed;
- Once the tag is closed it is NOT on the value stack at all! The item on the top of the value stack is the original action which called the JSP page which has the <s:action .. /> in it. Therefore, even though it now has a id or var attribute you cannot reference it in the normal way as it is not on the top of the stack. The way around this problem is to reference it by id or var using the # character, but carry on reading as there can be a problem with this.
Here is some example code for you, this is in your JSP:
<s:action namespace="/unsecured/show-latest-blog-posts" name="get-blog-posts" id="actionGetBlogPosts" />
Notice that the tag is closed and does not have any value for the body in this case. This just suited my need but it can have a body. However, if you use a body for the tag then you can't even reference it by the # character as it doesn't have an id or var until the tag is closed. This is the code for the execute method of my action:
List
The above is simple enough, get a list of blogPosts and set the property of our action with it in the standard way. Remember that this tag will not return the result if the parameter executeResult is not set to true. This means that we can return whatever we want as the result type and it will not make any difference. I return SUCCESS but you could return cabbage or footballs, the result will not be executed. If you need to change this behaviour and include the result of the action in your JSP then set executeResult to true. Next is the rest of the code for the JSP page, this goes after your <s:action .. /> tag has closed (in my case):
<s:property value="#actionGetBlogPosts.blogPosts"/>
This spits out the value of the actionBlogPosts.getBlogPosts() method that we set in out actions execute method. The important part here is the # which allows us to get a reference to our action. If you use the standard actionGetBlogPosts.blogPosts then you will get nothing! I am not certain but I think the # means to get a reference to an action by looking for it id or var attribute rather than looking on the top of the value stack.
If you find you really must have a body in your action tag then the only way I know of to get a property from your action, while in the body of that action, is to have the action place the required value in the session and then your JSP can retrieve it. This is the method shown on the Struts2 wiki page.
11.03.2009 03:16 - Posted by doahh - Comments: 3 - Java

Comments:
As always, any help with the documentation is appreciated ;-)
Using the action tag is indeed considered 'advanced', and it allows creation of pages using 'building blocks'.
But I cannot remember that it was not possible to access values outside the scope of the action tag (might have been changed) - I assume we use a copy of the valuestack there, and discard it afterwards. Maybe there still is a reference, but I'm not sure.
You could see if you could get the old ValueStack Explorer to work (but it was build for WebWork, so I'm not sure it'll work for S2.
12.03.2009 06:39 - Posted by Philip Luppens - Permalink
You are right, it is possible to reference the <s:action ... /> properties using <s:property ... /> if you use the # character to reference the action. I would not have worked that out if you hadn't prompted me to dig again; thanks.
I have updated the above post to include the new information.
13.03.2009 06:51 - Posted by doahh - Permalink
No problem - Struts 2 is an amazingly powerful and flexible framework, but there are times when you really have to dig into it to get the most out of it.
Btw, these small snippets/tutorials of yours are really great - you don't feel like coming over and helping us with the documentation? ;-)
20.03.2009 09:43 - Posted by Philip Luppens - Permalink