Spring MVCコントローラーメソッドが値を返さない場合は何を返しますか?


135

私はjQueryを使用$.getJSON()して、簡単なSpring MVCバックエンドへの非同期呼び出しを行っています。ほとんどのSpringコントローラーメソッドは次のようになります。

@RequestMapping(value = "/someURL", method = RequestMethod.POST)
public @ResponseBody SomePOJO getSomeData(@ModelAttribute Widget widget,
    @RequestParam("type") String type) {
    return someDAO.getSomeData(widget, type);
}   

各コントローラーが@ResponseBodyをJSONとして返すように設定しました。これは、クライアント側が期待するものです。

しかし、リクエストがコンテンツをクライアント側に返すことになっていない場合はどうなりますか?持てますか:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public @ResponseBody void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

そうでない場合、ここで使用する適切な構文は何ですか?


何も返さない場合、返送されるコンテンツはないと思いますか?
アラハント

1
私は、ソリューションのバージョン1では「成功」ブール値または類似のものをラップするだけでも、私はまだ何らかのPOJOを返すと思います。次に、すべてのAJAXメソッドに一貫したパターンあり、何かを返す必要があることが判明したときに、より簡単に構築できるものあります。
ミルハウス2012年

答えが示唆するものとは対照的に、2番目のスニペットで最初に持っていたものは完全に問題なく、POSTデータを処理する正しい方法です。
ブレット・ライアン

この場合はnullを返します。@RestController public class RESTControllerExample {@RequestMapping(value = "/ employees"、method = RequestMethod.GET)public void getEmployeeNames(){EmployeeSource.getEmployees(); System.out.println( "完了"); }}
spandey 2018年

回答:


256

voidを返すことができる場合は、メソッドに@ResponseStatus(value = HttpStatus.OK)のマークを付ける必要があります。@ ResponseBodyは不要です。

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

getメソッドのみが暗黙的に200ステータスコードを返します。

  • voidを返し、メソッドに次のマークを付けます @ResponseStatus(value = HttpStatus.OK)
  • オブジェクトを返し、マークを付ける @ResponseBody
  • HttpEntityインスタンスを返す

2
その間にランタイム例外が発生した場合、200ではなくHTTP 500が返されます。そのため、フロントエンドハンドルが失敗した場合、例外/エラーメッセージが正しく表示されます。
Lee Chee Kiam 2013

27
実際には、設定する必要はなく、設定する必要も@ResponseStatusありません。ハンドラーを持っ@ResponseBodyているvoidだけで十分です。
ブレット・ライアン

11
voidメソッドの場合は200ではなく204 No Contentを返すほうが良いと思います
raspacorp

1
@raspacorp 200はPOSTに適しています。
Brett Ryan

8
@BrettRyanはコメントとして、少なくともREST APIの場合、コンテンツの作成にPOSTが使用されるのが一般的な慣例です。この場合、通常、作成されたエンティティのID、完全に作成されたエンティティ、またはリンクが返されます読み取り操作に。コンテンツのない200ステータスの戻りは、REST APIの観点から混乱する可能性があります。
raspacorp 2014年

43

適切なヘッダーを持つResponseEntityを返すだけです。

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...){
....
return new ResponseEntity(HttpStatus.OK)
}

誰かが同じ問題に遭遇した場合、これは春の古いバージョン(4.1.1)では機能しませんでした。500エラーが発生しました。私は4.2.0にアップグレードしましたが、これはうまく機能します
ソース

これが、空の200を返すための私の好ましい方法です。Spring 4.1以降では、代わりにビルダーパターンを使用しています。return ResponseEntity.ok()。build();
GreenTurtle

3
コンパイルされているようですが、次の警告が表示されますResponseEntity is a raw type. References to generic type ResponseEntity<T> should be parameterized
ゴンザロ。

8

「ResponseEntity」オブジェクトを返すことができます。「ResponseEntity」オブジェクトの使用は、応答オブジェクト(応答本体とHTTPステータスコードを含む)を作成するときと、応答オブジェクトから情報を取得するときの両方に非常に便利です。

getHeaders()、getBody()、getContentType()、getStatusCode()などのメソッドを使用すると、ResponseEntityオブジェクトの読み取り作業が非常に簡単になります。

HTTPステータスコード204(コンテンツなし)のResponseEntityオブジェクトを使用する必要があります。これは、リクエストが適切に処理され、レスポンスの本文が意図的に空白であることを具体的に指定するためのものです。適切なステータスコードを使用して適切な情報を伝達することは、特に複数のクライアントアプリケーションで使用されるAPIを作成する場合に非常に重要です。


3
ブラウザで設定が@ResponseStatus(HttpStatus.NO_CONTENT)解決さXML Parsing Error: no root element foundれる
aliopi 2017

3

はい、@ ResponseBodyをvoid戻り値の型で使用できます。

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseBody
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

1
では、戻り値の型は何でしょうか?HTTPステータスコードですか?
spandey 2018年

@techBeginnerこの場合200(OK)。
Lakatos Gyula、2018年

2

空白を返すと何も間違ってあります@ResponseBodyし、あなたがすべきは、POSTリクエストしてください。

代わりにHTTPステータスコードを使用して、例外ハンドラルーチン内でエラーを定義します。あなたが持っているような通常のメソッドはあなたが200望むものである応答コードを返します、そして、どんな例外ハンドラーもそれからエラーオブジェクトと異なるコード(すなわち500)を返すことができます。


1

しかし、システムのサイズと機能が大きくなるにつれて、常にjsonを返すことはまったく悪い考えではないと思います。より建築的/「大規模設計」の問題です。

コードとデータという2つの既知のフィールドを持つJSONを常に再実行することを考えることができます。codeは、実行する操作の成功を指定する数値コードであり、dataは、要求された操作/サービスに関連する追加のデータです。

さあ、サービスプロバイダーのバックエンドを使用すると、サービスが正常に機能しているかどうかを確認できます。

だから私はこだわって、スプリングがこれを管理しないように、ハイブリッドの戻り操作を公開します(一部は他に何もデータを返さない...)。結局のところ、よりシンプルです。


0

これが非同期メソッドに対して私がやったコード例です

@RequestMapping(value = "/import", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void importDataFromFile(@RequestParam("file") MultipartFile file) 
{
    accountingSystemHandler.importData(file, assignChargeCodes);
}

メソッドから何かを返す必要はありません。このアノテーションを使用するために必要なのは、メソッドがすべてのケースでOKを返すようにするためです。

@ResponseStatus(value = HttpStatus.OK)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.