【发布时间】: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改成<s:url var="testJsonUrl" action="/testJsonAction"/>,没有区别。
标签: jquery json struts2 json-rpc struts2-json-plugin