Spring Boot Rest Controllerは、さまざまなHTTPステータスコードを返す方法を教えてください。


102

シンプルなREST APIにSpring Bootを使用していて、何かが失敗した場合に正しいHTTPステータスコードを返したいのですが。

@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)
@ResponseBody
@ResponseStatus( HttpStatus.OK )
public RestModel create(@RequestBody String data) {
    // code ommitted..
    // how do i return a correct status code if something fails?
}

SpringとSpring Bootの新機能である基本的な質問は、問題が発生した場合や失敗した場合に異なるステータスコードを返すにはどうすればよいですか?

回答:


117

使用できるオプションがいくつかあります。非常に良い方法は、呼び出された処理に例外とクラスを使用することです@ControllerAdvice

@ControllerAdvice
class GlobalControllerExceptionHandler {
    @ResponseStatus(HttpStatus.CONFLICT)  // 409
    @ExceptionHandler(DataIntegrityViolationException.class)
    public void handleConflict() {
        // Nothing to do
    }
}

またHttpServletResponse、コントローラーメソッドに渡して、応答コードを設定することもできます。

public RestModel create(@RequestBody String data, HttpServletResponse response) {
    // response committed...
    response.setStatus(HttpServletResponse.SC_ACCEPTED);
}

詳細については、この素晴らしいブログ投稿を参照してください:Spring MVCでの例外処理


注意

Spring MVCでは、@ResponseBodyアノテーションの使用は冗長です- @RestControllerアノテーションにすでに含まれています。


コメントと同じように、15分前にテストを行い、メソッドに '@ResponseBody'アノテーションを付けない '@RestController'を使用して、本文内ではなくForwardedURLとして文字列を返しました。私は自分の春/春
ブーツにかなり慣れ

@Anearion答えにタイプミスがあります-実際には '@RestController'ではなく '@RestControllerAdvice'が必要です。
yoliho 2017

それはタイプミスではありません。この部分は、コントローラの質問と注釈に関連しています
Jakub Kubrynski 2017

1
注、javax.servlet.http.HttpServletResponseすべてStatusCodes持たないように思わorg.springframework.http.HttpStatusないし。したがってHttpStatus.UNPROCESSABLE_ENTITY.value()、int値をresponse.setStatusに渡すために使用できます。また、これはを使用したエラー処理に完全に機能します@ExceptionHandler
イゴール

43

これを行う方法の1つは、ResponseEntityを戻りオブジェクトとして使用できることです。

@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)

public ResponseEntity<?> create(@RequestBody String data) {

if(everything_fine)
    return new ResponseEntity<>(RestModel, HttpStatus.OK);
else
    return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);

}

3
新しいバージョンのSpringでnullを使用する必要はありません。新しいResponseEntity <>(HttpStatus.NOT_FOUND)
Kong

4

このコードを試してください:

@RequestMapping(value = "/validate", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<ErrorBean> validateUser(@QueryParam("jsonInput") final String jsonInput) {
    int numberHTTPDesired = 400;
    ErrorBean responseBean = new ErrorBean();
    responseBean.setError("ERROR");
    responseBean.setMensaje("Error in validation!");

    return new ResponseEntity<ErrorBean>(responseBean, HttpStatus.valueOf(numberHTTPDesired));
}

これはかなり古い質問なので、参照するパッケージとバージョン情報を追加する必要があります。
ZF007 2018

の実装例を含めることができますErrorBeanか?
ブレントブラッドバーン、2018年

3

良い方法は、SpringのResponseStatusExceptionを使用することです

ResponseEntityまたは同様のものを返すのではなくResponseStatusExceptionHttpStatusandとcause を使用してコントローラから単にスローします。次に例を示します。

throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Cause description here");

または:

throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Cause description here");

これにより、次のような本文を持つHTTPステータス(例:400 Bad request)を含むクライアントへの応答が生成されます。

{
  "timestamp": "2020-07-09T04:43:04.695+0000",
  "status": 400,
  "error": "Bad Request",
  "message": "Cause description here",
  "path": "/test-api/v1/search"
}

2

カスタム定義のステータスコードを返す場合は、ResponseEntityを次のように使用できます。

@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)
public ResponseEntity<?> create(@RequestBody String data) {
    int customHttpStatusValue = 499;
    Foo foo = bar();
    return ResponseEntity.status(customHttpStatusValue).body(foo);
}

CustomHttpStatusValueは、標準のHTTPステータスコードの範囲内または範囲外の任意の整数です。


この流暢なAPIアプローチが気に入っています。
v.ladynev
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.