views:

3640

answers:

3

I have a question regarding the struts2 value stack. Let's say I have an Action class called RegisterAction that has an execute method as follows:

public String execute() {
    ValueStack stack = ActionContext.getContext().getValueStack();
    stack.push(new String("test string"));
    return SUCCESS;
}

My struts.xml looks like this:

<struts>
    <package name="default" extends="struts-default">
        <action name="*Register" method="{1}" class="vaannila.RegisterAction">
            <result name="populate">/register.jsp</result>
            <result name="input">/register.jsp</result>
            <result name="success">/success.jsp</result>
        </action>        
        <action name="*Test" method="{1}" class="vaannila.TestAction">
            <result name="test">/test.jsp</result>
            <result name="success">/success2.jsp</result>
        </action>        
    </package>
</struts>

So control will flow to the success.jsp after the execute method executes in that class.

My questions are:

1) how do I get that value I pushed on the stack in the success.jsp?

2) Let's say in success.jsp I have a <s:submit method="testMethod" /> that redirects to an action class called TestAction. In other words, from the Register page, the user clicks submit, and in the execute method of the RegisterAction we push the "test string" on the stack. Then we go to success.jsp. The success.jsp has a submit button that directs us to TestAction#testMethod. In TestAction#testMethod, is the value I pushed on the stack in RegisterAction#execute still there? How can I get it? I stepped through the eclipse debugger but I don't see the value.

Thanks.

+1  A: 

Ok, I figured this out.

1) The way I found to get objects on the value stack so we can access them from a jsp is like this:

Map<String, Object> context = new HashMap<String, Object>();
context.put("key", "some object");
context.put("key2", "another object");
ActionContext.getContext().getValueStack().push(context);

In other words, we can put a HashMap on the value stack containing the objects we need. Then, in the jsp, we can access the actual values like this:

<s:property value="key" />
<s:property value="key2" />

It will look through the value stack and find those values in the HashMap we pushed.

2) An instance of the action class is associated with just one request. So when we go to another action and then end up at another jsp, the stuff we pushed on the value stack from the first action won't be there since the other action has it's own value stack. reference: http://www.manning-sandbox.com/thread.jspa?messageID=93045

You guys can feel free to correct me if any of this is wrong or if there are smarter ways to do these things :).

Thanks.

dcp
A: 

Struts 2 adds your action to the top of the value stack when executed. So, the usual way to put stuff on the Value Stack is to add getters/setters for the values to your Action class. You still use the s:property tag to access the values.

A CRUD tutorial: http://struts.apache.org/2.1.6/docs/crud-demo-i.html

Nate
A: 

Normally, as Nate says, you will use a field in your action, since the action is always on the ValueStack. However, this doesn't work if you're writing interceptor code since the interceptor will be gone by the time the template (JSP/freemarker etc) is invoked. There you need to put some kind of java bean-like object on the ValueStack, just as you do above.

fool4jesus