web-dev-qa-db-ja.com

Postリクエストに@Requestparamアノテーションを使用できますか?

私はこのコントローラーメソッドを持っています:

@PostMapping(
        value = "/createleave",
        params = {"start","end","hours","username"})
public void createLeave(@RequestParam(value = "start") String start,
                        @RequestParam(value = "end") String end,
                        @RequestParam(value = "hours") String hours,
                        @RequestParam(value = "username") String username){
    System.out.println("Entering createLeave " + start + " " + end + " " + hours + " " + username);
    LeaveQuery newLeaveQuery = new LeaveQuery();
    Account account = accountRepository.findByUsername(username);
    newLeaveQuery.setAccount(account);
    newLeaveQuery.setStartDate(new Date(Long.parseLong(start)));
    newLeaveQuery.setEndDate(new Date(Long.parseLong(end)));
    newLeaveQuery.setTotalHours(Integer.parseInt(hours));
    leaveQueryRepository.save(newLeaveQuery);
}

ただし、このエンドポイントに投稿リクエストを送信すると、次のようになります

"{"timestamp":1511444885321,"status":400,"error":"Bad Request","exception":"org.springframework.web.bind.UnsatisfiedServletRequestParameterException","message":"Parameter conditions \"start, end, hours, username\" not met for actual request parameters: ","path":"/api/createleave"}"

@PostMappingアノテーションからparams引数を削除すると、より一般的なエラーが表示されます。最初の必須パラメーター(start)が見つかりませんが、実際にはパラメーターend、hours、およびユーザー名。

ポストポストmvcメソッドのパラメーターを取得する方法?

この投稿では、@RequestParamはgetメソッドにのみ使用できることを読みましたが、@RequestParamを削除して@PostMappingアノテーションのparams引数を使用しても動作しません。 @RequestBodyを使用できることは知っていますが、これらの4つのパラメーターだけのクラスを作成したくありません。誰も私がこの作品を作る方法を教えてもらえますか?

ありがとうございました

編集:私はここを読んでいます https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#params-- =引数paramsが、私が思っていた通りではないこと。条件として使用されているようです。パラメータのセットが値と一致する場合、エンドポイントコントローラーメソッドがアクティブになります。

12
Maurice

あなたが求めていることは根本的に間違っています。 POST要求は、@RequestBodyを介してマップされるボディペイロードでデータを送信します。@RequestParamは、/url?start=fooなどのURLパラメーターを介してデータをマップするために使用されます。あなたがしようとしているのは、@RequestParamを使用して@RequestBodyの仕事をすることです。

RESTコントローラの代替ソリューション

  • DTOクラスを導入します。これが最も推奨されるクリーンな方法です。
  • クラスの作成を本当に避けたい場合は、@RequestBody Map<String, String> payloadを使用できます。リクエストヘッダーに必ず'Content-Type': 'application/json'を含めてください。
  • 本当に@RequestParamを使用したい場合は、代わりにGETリクエストを使用し、URLパラメーター経由でデータを送信します。

MVCコントローラーの代替ソリューション

  • DTOクラスを導入し、注釈@ModelAttributeで使用します。
  • フォームデータをJSONに変換する場合、@RequestBody Map<String, String> payloadを使用できます。これを行うには、 この回答 を参照してください。

フォームデータのエンコードデータをMap<String, String>に直接マッピングすることはできません。

12
Sync

さて、@ Synchによる答えは根本的に間違っていると思います。質問されているのではありません。

  1. まず、GETまたはPOST HTTPメッセージを想定している多くのシナリオで@RequestParamを使用します。
  2. 最も投票された回答(再び@Synchによって)に参照されるPOSTメッセージのデータペイロード(本文)は、実際にはテキストデータであり、paramname=paramvalueキーと値のマッピング(完全に同じ)になります(-を参照) POST Message Body types here);
  3. docs.spring.io、Springドキュメントの公式ソース、 明確に述べている 、それ:

    Spring MVCでは、「リクエストパラメータ」はクエリパラメータ、フォームデータ、およびマルチパートリクエストのパーツにマッピングされます。

だから、答えはYESだと思う、@RequestParamクラスのメソッドのパラメータで@Controllerアノテーションを使用できますが、そのメソッドは@RequestMappingによってリクエストマッピングされ、Objectを期待しない限り、これは完全に合法であり、何も問題はありません。

4

_@RequestBody_を使用する代わりに_@RequestParam_を使用する必要があります。また、オブジェクト全体を要求の本体として提供する必要があります_@RequestParam_はPOSTメソッドではなくGET用です

public saveUser(@RequestBody User user) { do something with user }のようなことができます

そして、それは例えばユーザーオブジェクトとしてマッピングされます

2
Nenad Jovicic