1. ホーム

[解決済み] JAX-RS / ジャージーエラー処理をカスタマイズする方法は?

2022-04-07 09:09:05

質問

Jerseyを使ってJAX-RS(別名、JSR-311)を学んでいます。ルートリソースの作成に成功し、パラメータで遊んでいるところです。

@Path("/hello")
public class HelloWorldResource {

    @GET
    @Produces("text/html")
    public String get(
        @QueryParam("name") String name,
        @QueryParam("birthDate") Date birthDate) {

         // Return a greeting with the name and age
    }
}

これはとてもうまく動作し、現在のロケールで Date(String) コンストラクタが理解できるあらゆるフォーマット (YYYY/mm/dd や mm/dd/YYYY など) を処理できます。しかし、無効な値や理解できない値を指定すると、404レスポンスが返されます。

例えば

GET /hello?name=Mark&birthDate=X

404 Not Found

この動作をカスタマイズするにはどうしたらよいでしょうか?別のレスポンスコード(おそらく "400 Bad Request" )にするとか?エラーのログを取るのはどうでしょうか?トラブルシューティングを支援するために、カスタムヘッダに問題の説明("bad date format")を追加するとか?あるいは、5xxステータスコードとともに、詳細なエラーレスポンスを返すとか?

解決方法は?

JAX-RSでエラー処理の動作をカスタマイズするには、いくつかのアプローチがあります。 ここでは、その中から簡単な方法を3つ紹介します。

最初の方法は、WebApplicationException を継承した Exception クラスを作成することです。

public class NotAuthorizedException extends WebApplicationException {
     public NotAuthorizedException(String message) {
         super(Response.status(Response.Status.UNAUTHORIZED)
             .entity(message).type(MediaType.TEXT_PLAIN).build());
     }
}

そして、この新しく作成されたExceptionを投げるには、単純に。

@Path("accounts/{accountId}/")
    public Item getItem(@PathParam("accountId") String accountId) {
       // An unauthorized user tries to enter
       throw new NotAuthorizedException("You Don't Have Permission");
}

WebApplicationException は実行時の Exception なので、throws 節で例外を宣言する必要はないことに注意してください。 これは、クライアントに 401 レスポンスを返します。

2つ目の簡単な方法は、単純に WebApplicationException をコード内で直接使用することができます。 この方法は、独自のアプリケーション例外を実装する必要がない限りは有効です。

@Path("accounts/{accountId}/")
public Item getItem(@PathParam("accountId") String accountId) {
   // An unauthorized user tries to enter
   throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}

このコードもクライアントに401を返します。

もちろん、これは簡単な例に過ぎません。 必要であれば、例外をもっと複雑にして、必要なhttp応答コードを生成することができます。

もう一つの方法は、既存のExceptionをラップすることです。 ObjectNotFoundException を実装した小さなラッパークラスで構成されています。 ExceptionMapper インターフェースにアノテーションされた @Provider アノテーションを使用します。 これはJAX-RSランタイムに、ラップされたExceptionが発生した場合は ExceptionMapper .