web-dev-qa-db-ja.com

SpringMVCにHTTPPUTメソッドのリクエストパラメーターを設定できますか、それともpostを使用する必要がありますか? RESTfulになるためにどちらを使用する必要がありますか?

HTTP PUTである必要があると思うコントローラーアクションがありますが、コントローラーアクションで@RequestParamを使用しようとすると、Springが文句を言います。リクエストパラメータはHTTPPUTメソッドでは許可されていませんか?それがSpringがそれを拒否している理由ですか?

@RequestMapping(value = "/{helpDocumentId}/vote", method = RequestMethod.PUT)
public void voteHelpfulness(@PathVariable long helpDocumentId, @RequestParam boolean isHelpful) {
    helpManager.voteOnHelpDocument(helpDocumentId, isHelpful);
}

実行すると、次のエラーがスローされます。

org.springframework.web.bind.MissingServletRequestParameterException: Required boolean parameter 'isHelpful' is not present

もちろん、isHelpfulパラメータISが存在します。上記のコードをHTTPPOSTで完全に機能させることができるので、これが問題ではないことはわかっています。

     $.ajax({
            url: "/help/" + helpDocumentId + "/vote.json",
            type: "PUT",
            data: {
                isHelpful: isHelpful
            },
            success: function(response) {
                // ....
            }
     });

PUTは正しいhttpメソッドですか?このアクションはhelpDocumentを変更しますが、作成しません。

19
egervari

Since Spring 3.1、 HttpPutFormContentFilter _application/x-www-form-urlencoded_データの処理に使用できます:

HTTPPUTリクエスト中にServletRequest.getParameter*()ファミリーのメソッドを介してフォームエンコードされたデータを利用できるようにするフィルター。

サーブレット仕様では、フォームデータをHTTP POSTで使用できる必要がありますが、HTTP PUTリクエストでは使用できません。このフィルタは、コンテンツタイプが_'application/x-www-form-urlencoded'_であるHTTP PUTリクエストをインターセプトし、フォームでエンコードされたコンテンツをリクエストの本文であり、HTTP POSTリクエストの場合と同様に、フォームデータをリクエストパラメータとして使用できるようにするために、ServletRequestをラップします。

JSONなどの他の受信データの場合、415 Unsupported Mediaに遭遇しないように、 JQuery、Spring MVC @ RequestBody、JSON-連携させる で説明されているように_@RequestBody_が必要です。タイプ。

15
Arjan

SpringコントローラーはGET/HEAD/POST/PUT/DELETE/OPTIONS/TRACEをサポートしていますが、ブラウザーがこれらのリクエストメソッドを送信できない可能性があるため、機能しません。

回避策は、Springが提供する"org.springframework.web.filter.HiddenHttpMethodFilter"を使用することです。 requestメソッドの非表示パラメーターを渡す必要があります。このフィルターでサポートされるデフォルトのパラメーターは「_method」です。

詳細については、フィルタのjavadocを確認してください。

6
praveenj

これは、上記で示唆したように、_spring/servlet API_のバグのようです。実際には、PUTリクエストはリクエストパラメータではなくRequest Body (or payload)で機能することになっています。その意味で、サーブレットAPIとSpringの処理は正しいです。

そうは言っても、より適切ではるかに簡単な回避策は、_javascript/jQuery_呼び出しからデータ要素を渡さず、URL自体の一部としてパラメーターを渡すことです。つまり、GET呼び出しの場合と同じように、urlフィールドにパラメーターを設定します。

_$.ajax({
            url: "/help/" + helpDocumentId + "/vote.json" + "?param1=param2Val&..",
            type: "PUT",
            data: "",
            success: function(response) {
                // ....
            }
     });
_

これは単純なパラメーターでは機能するようになりましたが、複雑なJSONタイプでは機能しないと思います。お役に立てれば。

3
Ravi Bhatt

コメントの推奨事項に従い、@RequestParam@RequestBodyに変更しましたが、機能しました(私のパラメーターは文字列です)。

私の本番環境(@RequestParamを使用している場合)で失敗するのとまったく同じコードがローカルホストで正常に機能するため、これがSpringのバグであることに同意します。

0
AntonioOtero