WW-5070 Adds more sophisticated logic to search for the Root
diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java
index 0547e92..5c38e58 100644
--- a/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java
@@ -27,6 +27,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import com.opensymphony.xwork2.ModelDriven;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
@@ -68,8 +69,6 @@
*/
public class JSONResult implements Result {
- private static final long serialVersionUID = 8624350183189931165L;
-
private static final Logger LOG = LogManager.getLogger(JSONResult.class);
/**
@@ -212,12 +211,22 @@
}
protected Object findRootObject(ActionInvocation invocation) {
+ ValueStack stack = invocation.getStack();
Object rootObject;
if (this.root != null) {
- ValueStack stack = invocation.getStack();
+ LOG.debug("Root was defined as [{}], searching stack for it", this.root);
rootObject = stack.findValue(root);
} else {
- rootObject = invocation.getStack().peek(); // model overrides action
+ LOG.debug("Root was not defined, searching for #action");
+ rootObject = stack.findValue("#action");
+ if (rootObject instanceof ModelDriven) {
+ LOG.debug("Action is an instance of ModelDriven, assuming model is on the top of the stack and using it");
+ rootObject = stack.peek();
+ }
+ if (rootObject == null) {
+ LOG.debug("Neither #action nor ModelDriven, peeking up object from top of the stack");
+ rootObject = stack.peek();
+ }
}
return rootObject;
}
@@ -239,7 +248,6 @@
wrapSuffix));
}
- @SuppressWarnings("unchecked")
protected org.apache.struts2.json.smd.SMD buildSMDObject(ActionInvocation invocation) {
return new SMDGenerator(findRootObject(invocation), excludeProperties, ignoreInterfaces).generate(invocation);
}
@@ -286,7 +294,9 @@
}
/**
- * Sets the root object to be serialized, defaults to the Action
+ * Sets the root object to be serialized, defaults to the Action.
+ * If the Action implements {@link ModelDriven}, model will be used instead
+ * and assumptions is the Model was pushed on the top of the stack
*
* @param root OGNL expression of root object to be serialized
*/