Jersey と Jackson を使用して、Glassfish 3.1.2 で RESTful Web サービスを実行しています。
@Stateless
@LocalBean
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("users")
public class UserRestService {
private static final Logger log = ...;
@GET
@Path("{userId:[0-9]+}")
public User getUser(@PathParam("userId") Long userId) {
User user;
user = loadUserByIdAndThrowApplicableWebApplicationExceptionIfNotFound(userId);
return user;
}
}
予想される例外については、適切な をスローしWebApplicationException
ます。予期しない例外が発生した場合に返される HTTP 500 ステータスに満足しています。
これらの予期しない例外のログを追加したいと思いますが、検索しても、これについてどうすればよいかわかりません。
無益な試み
を使用してみましたThread.UncaughtExceptionHandler
が、メソッド本体内に適用されていることを確認できますがuncaughtException
、ハンドラーに到達する前に他の何かがキャッチされていない例外を処理しているため、そのメソッドは呼び出されません。
その他のアイデア: #1
一部の人々が使用しているのを私が見た別のオプションは、ExceptionMapper
すべての例外をキャッチしてから WebApplicationExceptions を除外する です。
@Provider
public class ExampleExceptionMapper implements ExceptionMapper<Throwable> {
private static final Logger log = ...;
public Response toResponse(Throwable t) {
if (t instanceof WebApplicationException) {
return ((WebApplicationException)t).getResponse();
} else {
log.error("Uncaught exception thrown by REST service", t);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
// Add an entity, etc.
.build();
}
}
}
このアプローチは機能する可能性がありますが、ExceptionMappers の使用目的、つまり特定の例外を特定の応答にマッピングすることの誤用のように感じます。
その他のアイデア: #2
ほとんどのサンプル JAX-RS コードは、Response
オブジェクトを直接返します。このアプローチに従って、コードを次のように変更できます。
public Response getUser(@PathParam("userId") Long userId) {
try {
User user;
user = loadUserByIdAndThrowApplicableWebApplicationExceptionIfNotFound(userId);
return Response.ok().entity(user).build();
} catch (Throwable t) {
return processException(t);
}
}
private Response processException(Throwable t) {
if (t instanceof WebApplicationException) {
return ((WebApplicationException)t).getResponse();
} else {
log.error("Uncaught exception thrown by REST service", t);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
// Add an entity, etc.
.build();
}
}
ただし、実際のプロジェクトはこの例ほど単純ではなく、この同じパターンを何度も実装する必要があり、Response を手動で作成する必要があることは言うまでもありません。
私は何をすべきか?
キャッチされていない例外のログを追加するためのより良い方法はありますか? これを実装する「正しい」方法はありますか?