2011-10-07 78 views
7

我有一個使用struts2-rest-plugin v.2.2.3的struts2應用程序。對REST插件沒有收到響應的Struts2的POST請求

當涉及到將請求路由到動作及其方法時,所有工作都很好,而且我還使用ModelDriven指定要在使用JSON和XML等擴展時序列化的對象。

我遇到的問題是,當我發送POST或PUT請求到struts層時,我只是得到一個空的響應。

我正在發送POST請求,如下所示:http://localhost:8080/alert-settings!update.json。我在該方法中有一個斷點,它被調用並且代碼運行並完成。我有一種感覺,問題可能是我試圖使用ModelDriven接口將回復發送給我,由於某種原因,其餘插件不喜歡這樣,但我不知道它爲什麼會這樣。

在使用其餘插件時,是否存在接收POST請求響應的已知問題?我到處尋找,真的找不到它。

任何幫助表示讚賞,我可以根據要求提供更多細節。

+0

我找不到解決的辦法上一次的設置,但我對通過返回DefaultHttpHeaders而不是改變響應代碼解決SUCCESS。我認爲這可能是POST和PUT請求的方式。 – noShowP

+0

嗨,我正在使用struts2-rest-plugin,並且無法使update()方法接受JSON有效內容並將其正確映射到模型。你介意分享你是如何做到的嗎?謝謝.. – shaunlim

回答

4

我遇到了同樣的問題。你有沒有試過在struts.xml中文件設置:

struts.rest.content.restrictToGET = false 

查看the rest plugin docs

1

其實我想通了,這是在其他線路插件造成的:

// don't return any content for PUT, DELETE, and POST where there are no errors 
if (!hasErrors && !"get".equalsIgnoreCase(ServletActionContext.getRequest().getMethod())) { 
    target = null; 
} 

這是org.apache.struts2.rest.RestActionInvocationselectTarget()方法。我覺得這很煩人,因爲它並不真正遵循REST體系結構,就像在某些情況下可以爲POST,DELETE和PUT請求返回響應對象一樣。

我工作圍繞這通過擴展RestActionProxyFactoryRestActionInvocation並指定使用這在我的支柱XML像這樣:

<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="restOverride" class="uk.co.ratedpeople.tp.rest.RPRestActionProxyFactory" /> 
<constant name="struts.actionProxyFactory" value="restOverride" /> 

這讓我使用Struts插件貫穿而在POST請求返回的對象。

RestActionProxyFactory

public class RPRestActionProxyFactory extends RestActionProxyFactory { 

    @Override 
    public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map extraContext, boolean executeResult, boolean cleanupContext) { 
     if (namespace.startsWith(this.namespace)) { 
      ActionInvocation inv = new RPRestActionInvocation(extraContext, true); 
      container.inject(inv); 
      return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext); 
     } else { 
      return super.createActionProxy(namespace, actionName, methodName, extraContext, executeResult, cleanupContext); 
     } 
    } 

} 

RestActionInvocation

public class RPRestActionInvocation extends RestActionInvocation { 

    public RPRestActionInvocation(Map extraContext, boolean pushAction) { 
     super(extraContext, pushAction); 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    protected void selectTarget() { 

     // Select target (content to return) 
     Throwable e = (Throwable)stack.findValue("exception"); 
     if (e != null) { 

      // Exception 
      target = e; 
      hasErrors = true; 

     } else if (action instanceof ValidationAware && ((ValidationAware)action).hasErrors()) { 

      // Error messages 
      ValidationAware validationAwareAction = ((ValidationAware)action); 

      Map errors = new HashMap(); 
      if (validationAwareAction.getActionErrors().size() > 0) { 
       errors.put("actionErrors", validationAwareAction.getActionErrors()); 
      } 
      if (validationAwareAction.getFieldErrors().size() > 0) { 
       errors.put("fieldErrors", validationAwareAction.getFieldErrors()); 
      } 
      target = errors; 
      hasErrors = true; 

     } else if (action instanceof ModelDriven) { 

      // Model 
      target = ((ModelDriven)action).getModel(); 

     } else { 
      target = action; 
     } 

     // don't return any content for PUT, DELETE, and POST where there are no errors 
//  if (!hasErrors && !"get".equalsIgnoreCase(ServletActionContext.getRequest().getMethod())) { 
//   target = null; 
//  } 
    } 

} 
+0

可能有更好的方法來解決這個問題,所以請分享,如果有的話。 – noShowP

0

我已經使用在過去的混合結果類型,返回JSON,XML和瓷磚例如Struts動作。我不確定是否推薦這樣做,但即使使用約定,也需要使用struts.xml進行一些配置。也許你已經這樣做了,不確定是否沒有足夠的信息來說明。

struts.xml的設置:

<constant name="struts.convention.default.parent.package" value="restful"/> 

<package name="restful" extends="rest-default, struts-default, json-default"> 
    <result-types> 
     <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" /> 
     <result-type name="json" class="com.googlecode.jsonplugin.JSONResult"/> 
    </result-types> 

    .... 
</package> 

我已經安裝額外的結果類型將在後面的具體行動中。在動作類中,您可以通過操作或方法來設置結果類型。

Action類:

@Results({ 
    @Result(name = "JsonSuccess", type = "json"), 
    @Result(name = "success", type = "tiles", location = "/tickets.tiles") 
}) 

public class EventController extends RestActionSupport implements ModelDriven<EventBean>{ 
    ... 
} 

別的東西需要注意的JSON結果,我注意到,當我有一個序列化的對象返回的結果是,如果該對象包含與其他複雜的對象getter/setter返回嵌入對象,我會經常收到一個空結果或沒有結果。我經常最終編寫json包裝器對象,用於我的json結果,其getter/setter只返回java類型(String,int,Boolean等),而不是嵌入式對象。我認爲使用委託getter/setter解決了這個問題,但我必須回頭看看一些舊代碼。

+0

我已經完成了你在這裏完成的任務,除了我已經使用了struts2-rest-plugin v.2.2.3來處理結果。因此,您不需要指定JsonSuccess類型,只需將.json添加到url的末尾,以便/job.json將調用JobAction的索引方法並以JSON格式返回其結果。這個問題具體到它的行爲,當請求是一個POST時,它不會從任何操作返回任何內容(所以POST到/job.json不會返回任何數據,只是成功或失敗)。 – noShowP