What objects are stored in ValueStack

250 Views Asked by At

This is my code below, when I execute it shows me the size 3, but when I pop the object out I am getting only 2 objects.

import java.util.*;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {

    private static final long serialVersionUID = 1L;
    private String name;

    public String execute() throws Exception {
        ValueStack stack = ActionContext.getContext().getValueStack();
        Map<String, Object> context = new HashMap<String, Object>();

        context.put("key1", new String("This is key1"));
        context.put("key2", new String("This is key2"));
        context.put("key3", new String("This is key3"));
        stack.push(context);

        System.out.println("Size of the valueStack: " + stack.size());

        for (int i = 0; i < stack.size(); i++) {
            System.out.println(i + ": " + stack.pop().toString());
        }
        return "success";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
 

Please, explain me whether I am doing it wrong?

Wnd I want to know that what are the objects stored in ValueStack and how can I retrieve those objects?

2

There are 2 best solutions below

8
Roman C On

You have mistreated the context and a map.

First, you got an action context and valueStack.

Then you created a map called context and pushed it to the stack.

Then you have started iterate over the stack, but the stack is a different object that has context pushed over.

To get your context back from the stack you need to pop() or peek() it from the valueStack. Then you can iterate it as a map.

The code:

context = (Map<String, Object>)stack.pop();
for (Map.Entry<String, Object> entry : context.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

8
Andrea Ligios On

There are two errors in your code, that are preventing the result to be printed correctly.


Error n.1

i <= stack.size() should be i < stack.size(), otherwise with 3 elements you'll try to print 4 elements (i is 0-based, size() is 1-based).
You are not encountering this error because of error n.2.


Error n.2

System.out.println(i + ": " + stack.pop().toString());

.pop(): Get the object on the top of the stack and remove it from the stack.

You should then store the size before the loop, because otherwise the size of the stack changes at every iteration.

This is what is happening:

for (int i = 0; i <= 3; i++) {

for (int i = 1; i <= 2; i++) {

for (int i = 2; i <= 1; i++) { // not performed. And you don't fall in error n.1.

Working code(s)

int size = stack.size();

for (int i = 0; i < size; i++) {
    System.out.println(i + ": " + stack.pop().toString());
}

This will print the result correctly, however it will alter the value stack; to prevent that, you should loop the value stack's objects from within an iterator, that you can obtain with the getRoot() method:

Iterator itr = stack.getRoot().iterator();
while (itr.hasNext()) {
    System.out.println(itr.next().toString()); 
    // or .getClass().getName(), ReflectionToStringBuilder.toString(), or whatever...
}