2014-01-26 2 views
2

Я использую следующую функцию JavaScript/jQuery для выполнения удаленного вызова процедуры.Использование JSON-RPC в Struts2

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

getUser() метод (в классе действия TestAction) с аннотацией @SMDMethod, как ожидается, будет вызван, когда данная кнопка нажата, но это не так.

Эта строка alert(JSON.stringify(user)); в обработчике success функции jQuery всегда предупреждает 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 с той же версией рамки.

+0

У вас есть имя папки admin_side? –

+0

Да, есть папка 'admin_side', где размещаются страницы JSP. Его местоположение - «WEB-INF/content/admin_side». – Tiny

+0

Не могли бы вы изменить пространство имен действия на «/»? –

ответ

1

Обязательно ли иметь только запрос POST при использовании JSON-RPC?

да, он работает только с запросом POST

Также includeProperties не имеет никакого эффекта

includeProperties имеет эффект, если это параметр json перехватчика. Не путайте имя параметра, используемого с результатом 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; 
} 
+0

Это действительно сработало. Я неправильно предположил, что параметры 'includeProperties' должны быть установлены на' user'. Однако я должен был использовать этот regx (как вы упомянули в одном из ответов), '' result \\ [\\ d + \\] \\. StateId, result \\ [\\ d + \\] \\. StateName "' при получении списка состояний из базы данных. Просто вырвать точку '.' как' 'result \\. StateId, result \\. StateName" "привело к получению пустого списка в ответе. У меня теперь есть еще одна проблема, которая касается Spring Security !!! Извините, я дал вам много неприятностей! – Tiny

+0

Можем ли мы иметь параметризованный метод '@ SMDMethod'? Обратившись к примеру в вопросе, можем ли мы передать параметры методу 'getUser()'? Эта [wiki] (https://cwiki.apache.org/confluence/display/WW/JSON+Plugin) (последний раздел, JSON-RPC) показывает примеры, но использует плагин dojo. – Tiny

+0

«Результат» является корневым объектом, который сериализуется, и это объект, возвращаемый методом. В этом примере это «Пользовательский» компонент, поэтому регулярное выражение будет просто точкой ссылки на свойство. Если объектом возврата является List, то он будет, как вы писали, не тестировал его. Параметры должны передаваться с параметрами: [] 'и есть' @ SMDMethodParameter'. –

Смежные вопросы