I use the following JavaScript/jQuery function to make a remote procedure call.
<script src="../js/jquery-1.8.0.min.js" type="text/javascript"></script>
<s:url var="testJsonUrl" action="testJsonAction"/>
var timeout;
var request;
$(document).ready(function(){
$("#btnUser").click(function(){
if(!request)
{
request = $.ajax({
datatype:"json",
type: "GET",
data: JSON.stringify({jsonrpc:'2.0', method:'getUser', id:'jsonrpc'}),
contentType: "application/json-rpc; charset=utf-8",
url: "<s:property value='#testJsonUrl'/>",
success: function(response)
{
var user = response.result;
alert(JSON.stringify(user)); //Always alerts "undefined".
},
complete: function()
{
timeout = request = null;
},
error: function(request, status, error)
{
if(status!=="timeout"&&status!=="abort")
{
alert(status+" : "+error);
}
}
});
timeout = setTimeout(function() {
if(request)
{
request.abort();
alert("The request has been timed out.");
}
}, 30000);
}
});
});
The above function is called, when a button is clicked as follows.
<s:form namespace="/admin_side" action="Test" validate="true" id="dataForm" name="dataForm">
<input type="button" name="btnUser" id="btnUser" value="Click"/>
</s:form>
The action class in which the method is to be invoked is as follows.
import com.opensymphony.xwork2.ActionSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.ResultPath;
import org.apache.struts2.json.annotations.SMDMethod;
import util.User;
@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value = "json-default")
public final class TestAction extends ActionSupport
{
private User user;
public TestAction() {}
@SMDMethod
public User getUser()
{
user = new User();
user.setName("Tiny");
user.setLocation("India");
try {
user.setDob(new SimpleDateFormat("dd-MMM-YYYY").parse("29-Feb-2000"));
} catch (ParseException ex) {
Logger.getLogger(TestAction.class.getName()).log(Level.SEVERE, null, ex);
}
return user;
}
public void setUser(User user) {
this.user = user;
}
@Action(value = "testJsonAction",
results = {
@Result(type = "json", params = {"enableSMD", "true", "excludeNullProperties", "true"})},
interceptorRefs = {
@InterceptorRef(value = "json", params = {"enableSMD", "true"})})
public String executeAction() throws Exception {
return SUCCESS;
}
@Action(value = "Test",
results = {
@Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
@Result(name = ActionSupport.INPUT, location = "Test.jsp")},
interceptorRefs = {
@InterceptorRef(value = "defaultStack", params = {"params.acceptParamNames", "", "params.excludeMethods", "load", "validation.validateAnnotatedMethodOnly", "true"})})
public String load() throws Exception {
//This method is just needed to return a view on page load.
return ActionSupport.SUCCESS;
}
}
The User
class:
public class User
{
private String name;
private Date dob;
private String location;
//Setters & getters.
}
The getUser()
method (in the action class TestAction
) annotated with @SMDMethod
is expected to be invoked, when the given button is clicked but it does not.
This line alert(JSON.stringify(user));
in the success
handler of the jQuery function always alerts undefined
.
Using a direct link in the address bar like,
http://localhost:8080/TestStruts/admin_side/testJsonAction.action
returns the following string.
{
"methods": [{
"name": "getUser",
"parameters": []
}],
"serviceType": "JSON-RPC",
"serviceUrl": "\/TestStruts\/admin_side\/testJsonAction.action",
"version": ".1"
}
What is missing here? Why does not JSON-RPC
work?
PS : I'm using Struts2-json-plugin-2.3.16
with same version of the framework.
Is it mandatory to have only the POST request while using JSON-RPC?
yes, it only works with POST request
Also
includeProperties
has no effect
includeProperties
has effect if it's a parameter to json
interceptor. Don't confuse the name of parameter used with json
result.
the field
dob
in this case, should have been excluded
In this case better to use excludeProperties
parameter to interceptor, like this
@Action(value = "testJsonAction",
results = {
@Result(type = "json", params = {"enableSMD", "true"})},
interceptorRefs = {
@InterceptorRef(value = "json", params = {"enableSMD", "true", "excludeProperties", "result\\.dob"})})
public String executeAction() throws Exception {
return SUCCESS;
}
来源:https://stackoverflow.com/questions/21368194/using-json-rpc-in-struts2