2011-10-07 24 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を返すことによって応答コードを変更することで決着しました成功の私は、これが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; 
} 

これはselectTarget()方法でorg.apache.struts2.rest.RestActionInvocationであるが。 POST、DELETE、およびPUT要求に対する応答オブジェクトを返すことができるオプションのように、実際にはRESTアーキテクチャに従わないため、これはかなり厄介なものです。

は私がRestActionProxyFactoryRestActionInvocationを拡張し、そのように私の支柱をXMLでこれを使用することを指定することでこの問題を回避働いていた:これは私がストラットはPOSTリクエストでオブジェクトを戻しながら全体のプラグインを使用することができます

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

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

私は、余分な結果タイプは、後に特定のアクションで使用されるように設定しています。アクションクラスでは、結果のタイプをアクションまたはメソッドで設定できます。

アクションクラス:他

@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では、空の結果が返されるか、結果が返されないことがよくあります。私はしばしば、Javaの型(String、int、Booleanなど)のみを返し、埋め込みオブジェクトは返さないgetters/setterを使用してjsonの結果に使用するjsonラッパーオブジェクトを作成します。私はdelegate getters/settersを使ってこれを解決したと思いますが、私は戻って古いコードを見ていく必要があります。

+0

私はあなたのために結果を扱うstruts2-rest-plugin v.2.2.3を使用したことを除いて、ここでyouv'eがやったことをしたことがあります。だから、あなたはちょうど/job.jsonがJobActionのインデックスメソッドを呼び出し、その結果をJSONで返すように、URLの最後に.jsonを追加するJsonSuccessタイプを指定する必要はありません。質問は、リクエストがPOSTのときに何らかのアクションから何も返さないという振る舞いに特有のものでした(したがって、POSTは/job.jsonへのPOSTはデータを返さず、成功または失敗のみ)。 – noShowP

関連する問題