Using JSON-RPC in Struts2

拈花ヽ惹草 提交于 2019-12-10 11:24:42

问题


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.


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!