web-dev-qa-db-ja.com

すべての例外をキャッチし、ジャージーでカスタムエラーを返す

ジャージーレストサービスで予期しない例外をすべてキャッチしたい。したがって、ExceptionMapperを作成しました。

@Provider
public class ExceptionMapper implements javax.ws.rs.ext.ExceptionMapper<Exception> {
    private static Logger logger = LogManager.getLogManager().getLogger(ExceptionMapper.class.getName());

    @Override
    public Response toResponse(Exception e) {
        logger.log(Level.SEVERE, e.getMessage(), e);

        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("Internal error").type("text/plain").build();
    }
}

マッパーは本当にすべての例外をキャッチします。したがって、私は書くことができません:

public MyResult getById(@PathParam("id")) {
    if (checkAnyThing) {
        return new MyResult();
    }
    else {
        throw new WebApplicationException(Response.Status.NOT_FOUND);
    }
}

これはマッパーによってキャッチされます。今私は書く必要があります:

public Response getById(@PathParam("id") {
    if (checkAnyThing) { {
        return Response.ok().entity(new MyResult()).build();
    }
    else {
        return Response.status(Response.Status.NOT_FOUND).build();
    }
}

これは、すべての予期しない例外をキャッチし、ジャージーでエラー(エラーコード)を返す正しい方法ですか?または、他の(より正しい)方法はありますか?

20
Dominic

WebApplicationException には getResponse があり、そこからResponseを取得できます。したがって、マッパーでWebApplicationExceptionを確認できます。たぶん

@Override
public Response toResponse(Throwable error) {
    Response response;
    if (error instanceof WebApplicationException) {
        WebApplicationException webEx = (WebApplicationException)error;
        response = webEx.getResponse();
    } else {
        response = Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                .entity("Internal error").type("text/plain").build();
    }
    return response;
}

このようにして、スローされたWebApplicationExceptionのインスタンスは、デフォルトの応答を返します。これは実際には他のいくつかの例外も処理し、アプリケーションによって明示的にスローされません。 WebApplicationExceptionには、JAX-RSによってスローされるその階層の下にいくつかの例外があり、そのために事前定義された応答/ステータスコードがラップされます。

Exception                      Status code    Description
-------------------------------------------------------------------------------
BadRequestException            400            Malformed message
NotAuthorizedException         401            Authentication failure
ForbiddenException             403            Not permitted to access
NotFoundException              404            Couldn’t find resource
NotAllowedException            405            HTTP method not supported
NotAcceptableException         406            Client media type requested 
                                                            not supported
NotSupportedException          415            Client posted media type 
                                                            not supported
InternalServerErrorException   500            General server error
ServiceUnavailableException    503            Server is temporarily unavailable 
                                                            or busy

とはいえ、これらの例外をコードで明示的にスローして、より意味のある値を与えることができます。

一般的に言えば、上の表のように応答メッセージ/ステータスコードを変更したくない場合を除き、上記の例は不要な場合がありますが、例外の階層にはすでにいくつかの一般的なマッピングがあります。そして、ほとんどの場合、予期しない例外はすでにInternalServerErrorExceptionにマップされています

29
Paul Samsotha