Spring ResponseStatusException

Spring ResponseStatusException

1. 概要

このクイックチュートリアルでは、Spring 5で導入された新しいResponseStatusExceptionクラスについて説明します。 このクラスは、HTTPステータスコードのHTTP応答への適用をサポートします。

RESTfulアプリケーションは、HTTP要求の成功または失敗をreturning the right status code in the response to the clientで伝達できます。 簡単に言えば、適切なステータスコードは、クライアントがアプリケーションがリクエストを処理している間に発生した可能性のある問題を識別するのに役立ちます。

2. ResponseStatus

ResponseStatusException,について詳しく説明する前に、@ResponseStatusのアノテーションを簡単に見てみましょう。 このアノテーションは、HTTPステータスコードをHTTP応答に適用するためにSpring 3で導入されました.

@ResponseStatusアノテーションを使用して、HTTP応答のステータスと理由を設定できます。

@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Actor Not Found")
public class ActorNotFoundException extends Exception {
    // ...
}

HTTP要求の処理中にこの例外がスローされた場合、応答にはこのアノテーションで指定されたHTTPステータスが含まれます。

@ResponseStatusアプローチの1つの欠点は、例外を除いて密結合が作成されることです。 この例では、タイプActorNotFoundExceptionのすべての例外が、応答で同じエラーメッセージとステータスコードを生成します。

3. ResponseStatusException

ResponseStatusExceptionは、@ResponseStatusのプログラムによる代替であり、HTTP応答にステータスコードを適用するために使用される例外の基本クラスです。 これはRuntimeExceptionであるため、メソッドシグネチャに明示的に追加する必要はありません。

Springは、ResponseStatusException:を生成するための3つのコンストラクターを提供します

ResponseStatusException(HttpStatus status)
ResponseStatusException(HttpStatus status, java.lang.String reason)
ResponseStatusException(
  HttpStatus status,
  java.lang.String reason,
  java.lang.Throwable cause
)

ResponseStatusException,コンストラクター引数:

  • status – HTTP応答に設定されたHTTPステータス

  • reason – HTTP応答に設定された例外を説明するメッセージ

  • 原因–ResponseStatusExceptionThrowableの原因

注:Springでは、HandlerExceptionResolverは、発生した例外をインターセプトして処理し、コントローラーによって処理されません。

これらのハンドラーの1つであるResponseStatusExceptionResolver,は、ResponseStatusExceptionまたは@ResponseStatusで注釈が付けられたキャッチされない例外を探し、HTTPステータスコードと理由を抽出してHTTP応答に含めます。

3.1. ResponseStatusExceptionのメリット

ResponseStatusExceptionの使用には、いくつかの利点があります。

  • まず、同じタイプの例外を個別に処理し、異なるステータスコードを応答に設定して、密結合を減らすことができます。

  • 第二に、不必要な追加の例外クラスの作成を回避します

  • 最後に、例外はプログラムで作成できるため、例外処理をより詳細に制御できます。

4. 例

4.1. ResponseStatusExceptionを生成する

ここで、ResponseStatusExceptionを生成する例を見てみましょう。

@GetMapping("/actor/{id}")
public String getActorName(@PathVariable("id") int id) {
    try {
        return actorService.getActor(id);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
          HttpStatus.NOT_FOUND, "Actor Not Found", ex);
    }
}

Spring Bootはデフォルトの/errorマッピングを提供し、HTTPステータスと例外メッセージを含むJSON応答を返します。

応答は次のようになります。

$ curl -i -s -X GET http://localhost:8080/actor/8
HTTP/1.1 404
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 28 Jan 2018 19:48:10 GMT

{
    "timestamp": "2018-01-28T19:48:10.471+0000",
    "status": 404,
    "error": "Not Found",
    "message": "Actor Not Found",
    "path": "/actor/8"
}

4.2. 異なるステータスコード-同じ例外タイプ

次に、同じタイプの例外が発生したときに、異なるステータスコードがHTTP応答にどのように設定されるかを見てみましょう。

@PutMapping("/actor/{id}/{name}")
public String updateActorName(
  @PathVariable("id") int id,
  @PathVariable("name") String name) {

    try {
        return actorService.updateActor(id, name);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
          HttpStatus.BAD_REQUEST, "Provide correct Actor Id", ex);
    }
}

応答は次のようになります。

$ curl -i -s -X PUT http://localhost:8080/actor/8/BradPitt
HTTP/1.1 400
...
{
    "timestamp": "2018-02-01T04:28:32.917+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "Provide correct Actor Id",
    "path": "/actor/8/BradPitt"
}

5. 結論

このクイックチュートリアルでは、プログラムでResponseStatusExceptionを作成する方法について説明しました。

また、@ResponseStatusアノテーションよりも、プログラムでHTTPレスポンスにHTTPステータスコードを設定する方が優れていることを強調しました。

いつものように、完全なソースコードはover on GitHubで利用できます。