REST Web サービスに jersey を使用しています。
サービス層からオブジェクトを取得しないときはいつでも NotFoundException(Package com.sun.jersey.api) をスローして、404 応答すべてを処理しています。
例えば
@GET
@Path("/{folderID}")
@Produces(MediaType.APPLICATION_JSON)
public Response getFolder(@PathParam("folderID") int folderID) {
.
.
.
Folder folderObj = folderService.getFolder(folderID);
if(folderObj == null){
throw new NotFoundException("Folder with ID '"+folderID+"' not found.");
}
}
この例外用に ExceptionMapper を作成しました。
@Provider
public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {
public Response toResponse(NotFoundException ex) {
ErrorMesage errorMessage = new ErrorMessage();
errorMessage.setCode(Status.NOT_FOUND.getStatusCode());
errorMessage.setMessage(ex.getMessage());
return Response.status(Status.NOT_FOUND)
.entity(errorMessage)
.type(MediaType.APPLICATION_JSON)
.build();
}
}
そのため、不明なフォルダー ID をパス パラメーターとして指定すると、例外がスローされますが、NotFoundExceptionMapper のコードは呼び出されません。(マッパーでJSONで応答を返しているにもかかわらず、応答に例外メッセージが表示されますが、「プレーンテキスト」として表示されます。デバッグブレークポイントもヒットしません)。
また、URIに間違ったリソース名を入力すると、上記の例外マッパーが呼び出されますが、パスパラメーターが正しくない場合は呼び出されません。
他のすべての例外に対応するために、以下のような例外マッパーも追加しました。
public class GenericExceptionMapper implements ExceptionMapper<Throwable>{
public Response toResponse(Throwable ex) {
ErrorMessage errorMessage = new ErrorMessage();
errorMessage.setCode(Status.INTERNAL_SERVER_ERROR.getStatusCode());
errorMessage.setMessage(ex.getMessage());
return Response.status(errorMessage.getCode())
.entity(errorMessage)
.type(MediaType.APPLICATION_JSON)
.build();
}
上記のコードは、例外 (マップされた例外以外) がスローされるたびに呼び出され、適切な JSON 応答が得られます。
では、ここで NotFoundException の何が問題になっているのでしょうか? 私はこれについてグーグルで検索し、NotFoundException のソースも調べましたが、役立つものは何も見つかりませんでした。これについて教えてください。