次のように動作する必要がある NotFoundExceptionMapper という ExceptionMapper があります。
@Provider
public class NotFoundExceptionMapper implements
ExceptionMapper<NotFoundException> {
public Response toResponse(NotFoundException e) {
if(e originated from ClassA)
// create a complex ResponseTypeA and return it
if(e originated from ClassB)
// create a complex ResponseTypeB and return it
return DefaultResponseType;
}
}
このようなものが必要な理由は、私の REST 層では、クラス ClassA のすべてのメソッドが本質的にまったく同じ try & catch エラー処理を持っているため、冗長なコードが多くなるからです。クラスBも同様です。classA と ClassB の唯一の違いは、classA のメソッドは classB のメソッドとは異なる Response タイプを返す必要があることです。
ExceptionMapper は、冗長なエラー処理コードを回避する優れた方法のようです。あとは、例外の発生元 (ClassA または ClassB) を決定し、普遍的なエラー処理を実行して、適切な応答タイプを返すことだけです。
私はすでにこのための作業コードを持っていますが、これを行うためのよりエレガントな方法があるのだろうか. まだまだジャージーには慣れていないことがたくさんあるので、見落としている可能性が高いです。
コードは非常に単純で、UriInfo インジェクションを使用して例外の発生元を識別します。
私のExceptionMapper:
@Provider
public class NotFoundExceptionMapper implements
ExceptionMapper<NotFoundException> {
@Context
UriInfo uriInfo;
public Response toResponse(NotFoundException e) {
// MyResponseBuilder decides which response type to return:
return MyResponseBuilder.buildResponse(uriInfo, e, Response.Status.NOT_FOUND);
}
}
クラス MyResponseBuilder がすべての魔法を行います。UriInfo を分析し、適切な応答タイプを返します。
public class MyResponseBuilder {
public static Response buildResponse(UriInfo uriInfo, Exception e, Status status) {
List<Object> matchedRes = uriInfo.getMatchedResources();
if(matchedRes.size() == 1) {
Object res = matchedRes.get(0);
if(res.getClass() == ClassA.class) {
ResponseTypeA resp = new ResponseTypeA();
// populate resp with infos
return Response.status(status).entity(resp).build();
}
else if(res.getClass() == ClassB.class) {
ResponseTypeB resp = new ResponseTypeB();
// populate resp with infos
return Response.status(status).entity(resp).build();
}
}
return Response.status(status).build(); // default response
}
}
そして、それが機能している間、同じ URI で動作する複数の一致するリソースがある場合、いくつかの厄介な問題を引き起こす可能性があります。適切に処理された場合 (つまり、正しいリソースを見つけた場合) は発生しません。それでも、これが満足のいく解決策であるとは思いません。
この問題に対するより洗練された方法は、NotFoundExceptionMapper_ThatReturnsResponseTypeA を直接 ClassA に関連付け、別の NotFoundExceptionMapper_ThatReturnsResponseTypeB を ClassB に関連付けることです。しかし、私はそうする方法を見つけていません。
方法はありますか?