1.概要

このクイックチュートリアルでは、Spring 5で導入された新しい

ResponseStatusException

クラスについて説明します。このクラスはHTTPステータスコードのHTTP応答への適用をサポートします。

RESTfulアプリケーションは、

クライアントへの応答で正しいステータスコードを返すことによって

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

2.

ResponseStatus


ResponseStatusExceptionを詳しく調べる前に、

@ ResponseStatus

アノテーションを見てみましょう。このアノテーションは、HTTPステータスコードをHTTPレスポンスに適用するためにSpring 3で導入されました


.

__

HTTPレスポンスのステータスと理由を設定するために

@ ResponseStatus

アノテーションを使うことができます。

@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レスポンスに設定された例外を説明するメッセージ

  • cause –

    ResponseStatusException



    Throwable

    の原因

注意:Springでは、

HandlerExceptionResolver

は、コントローラによって処理されなかった、発生した例外をすべて傍受して処理します。

これらのハンドラの1つ、

ResponseStatusExceptionResolver、

は、

ResponseStatusException

または

@ ResponseStatus

でアノテーションが付けられたキャッチされていない例外を探し、HTTPステータスコードとreasonを抽出して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レスポンスに設定する方がプログラム的に優れている方法を強調しました。

いつものように、完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-5[over on GitHub]から入手可能です。