Reputation: 1138
Working on one of the big web application with struts 2.x ( currently using struts-core 2.3.4.1 )
In this app when I call an action through ajax , after returning from an action, an unrelated some other action getting called. I didn't find the solution even after spending many days.
Later I thought to create simple sample app , which has just two actions, no web service calls, just one jsp, and only one action mapped ( I tried mapping other action too in struts.xml) again the same problem
Please find the code below
Struts Action Class
package lpaction;
public class PlanAction {
public String updatePlan() {
return "PLAN_ACTION_SUCCESS";
}
public String getPlans() {
return "PLAN1_ACTION_SUCCESS";
}
}
JSP Code
<%@page import="org.json.JSONArray"%>
<%@page import="org.json.JSONObject"%>
<%@ page contentType="text/html; charset=utf-8" language="java"
import="java.sql.*" errorPage=""%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Client</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<link rel="icon" href="../images/favicon.png" type="image/png" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="<%=request.getContextPath()%>/js/Libs/utility.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/Libs/jquery1.10.js"> </script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/Libs/ui/jquery-ui.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/Libs/jquery.ba-throttle-debounce.min.js"></script>
<script>
function callme(){
var formdata = "";
console.log("formData = "+formdata);
$.ajax({
type: 'POST',
url: 'plan',
contentType: "application/x-www-form-urlencoded",
async: false,
data :formdata,
cache: false,
processData:false,
datatype: "json",
success: function(response) {
alert("Success"+response);
},
error: function(e) {
alert("Fail");
}
});
}
</script>
</head>
<body>
<div id="wrap">
<input type="button" onclick="callme()"> press me </>
</div>
</body>
</html>
Struts.xml file
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package name="lessonPlan" extends="json-default">
<action name="plan" class="lpaction.PlanAction"
method="updatePlan">
<result name="PLAN_ACTION_SUCCESS" type="json" />
<result name="PLAN_ACTION_FAIL" type="json" />
</action>
<!-- <action name="plan1" class="lpaction.PlanAction"
method="getPlans">
<result name="PLAN1_ACTION_SUCCESS" type="json" />
<result name="PLAN1_ACTION_FAIL" type="json" />
</action> -->
</package>
</struts>
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<filter>
<filter-name>testClient</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>testClient</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
If I put breakpoint in both action methods, the first action method will be called after that second action method will call.
Why second action method is getting called ? Infact second action is not at all mapped ( Note I tried to uncomment that action mapping in struts.xml, still same problem )
I am using the following JAR files
Upvotes: 2
Views: 882
Reputation: 4784
Reason your getPlans
method is called when you call plan
action is that the method name starts with get
. Since you have not specified any Customized Serialization and Deserialization for your JSON Result everything that starts with get
will be Serialized, that means at the time of generating response getPlans
method will be called because of Serialization.
You can change the action method name to overcome this issue, also refer this JSON Plugin Documentation for controlling your json object sent in response. If you don't control json object in response it can lead to unintentional data exposure which intern cause security risks and .
Update: As per documents
The serialization process is recursive, meaning that the whole object graph, starting on the action class (base class not included) will be serialized (root object can be customized using the "root" attribute)
This means every thing in action will be serialized(so that means every method with prefix get
will be called), And this is done with recursion that is going in depth of object excluding base class.
Upvotes: 5