【问题标题】:Using JSON-RPC in Struts2在 Struts2 中使用 JSON-RPC
【发布时间】:2014-01-26 19:32:20
【问题描述】:

我使用以下 JavaScript/jQuery 函数进行远程过程调用。

<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);
        }
    });
});

上面的函数被调用,当一个按钮被点击时,如下所示。

<s:form namespace="/admin_side" action="Test" validate="true" id="dataForm" name="dataForm">
    <input type="button" name="btnUser" id="btnUser" value="Click"/>
</s:form>

要调用该方法的动作类如下。

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;
    }
}

User 类:

public class User
{
    private String name;
    private Date dob;
    private String location;

    //Setters & getters.
}

当给定按钮被点击但没有被点击时,预计会调用带有@SMDMethod 注释的getUser() 方法(在动作类TestAction 中)。

jQuery 函数的success 处理程序中的这一行alert(JSON.stringify(user)); 总是提醒undefined

在地址栏中使用直接链接,例如,

http://localhost:8080/TestStruts/admin_side/testJsonAction.action

返回以下字符串。

{
    "methods": [{
        "name": "getUser",
        "parameters": []
    }],

    "serviceType": "JSON-RPC",
    "serviceUrl": "\/TestStruts\/admin_side\/testJsonAction.action",
    "version": ".1"
}

这里缺少什么?为什么JSON-RPC 不起作用?

PS : 我正在使用 Struts2-json-plugin-2.3.16 和相同版本的框架。

【问题讨论】:

  • 你有文件夹名admin_side吗?
  • 是的,有一个文件夹 admin_side 放置 JSP 页面。它的位置是WEB-INF/content/admin_side
  • 您能否将操作的命名空间更改为“/”?
  • 或者更好的办法是将方法的名称更改为其他名称“doSomething”。
  • 方法改名为doSomething(),URL改成&lt;s:url var="testJsonUrl" action="/testJsonAction"/&gt;,没有区别。

标签: jquery json struts2 json-rpc struts2-json-plugin


【解决方案1】:

使用 JSON-RPC 时是否必须只有 POST 请求?

是的,它只适用于 POST 请求

同样includeProperties也没有效果

includePropertiesjson 拦截器的参数时有效。不要将使用的参数名称与json 结果混淆。

在这种情况下,字段 dob 应该被排除

这种情况下最好使用excludeProperties参数来拦截,像这样

@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;
}

【讨论】:

  • 这确实有效。我错误地认为includeProperties 的参数将设置为user。但是,我在从数据库中检索状态列表时不得不使用这个正则表达式(正如您在其中一个答案中提到的)"result\\[\\d+\\]\\.stateId, result\\[\\d+\\]\\.stateName"。像"result\\.stateId, result\\.stateName" 这样简单地转义一个点. 会导致在响应中获取一个空列表。我现在还有一个关于 Spring Security 的新问题!对不起,给你添了很多麻烦!
  • 我们可以有一个参数化的@SMDMethod 方法吗?参考问题中的例子,我们可以将参数传递给getUser()方法吗?这个wiki(最后一节,JSON-RPC)显示了示例,但它使用了 dojo 插件。
  • result 是一个正在序列化的根对象,它是方法返回的对象。在本例中,它是一个User bean,因此正则表达式将只是对属性的点引用。如果返回对象是 List 那么它就像你写的那样,没有测试它。参数应该用parameters:[]传递,还有@SMDMethodParameter
  • data: JSON.stringify({jsonrpc:'2.0', method:'getUser', id:'jsonrpc', parameters:[{'userId':1}]}) 在行动课上,public User getUser(@SMDMethodParameter(name="userId")Long userId){...} 说,SEVERE: Method getUser could not be found in action class. 我遗漏了一些明显的东西。
  • 这是一个有效的 json 吗?
猜你喜欢
  • 2010-09-18
  • 2014-02-20
  • 2014-09-24
  • 1970-01-01
  • 2013-09-12
  • 2014-02-16
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
相关资源
最近更新 更多