我有一个名为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&amp;捕获错误处理,导致大量冗余代码。 ClassB也是如此。 classA和ClassB之间的唯一区别是classA中的方法需要返回与classB中的方法不同的Response类型。
ExceptionMapper似乎是避免冗余错误处理代码的好方法。剩下要做的就是决定异常来自哪里(ClassA或ClassB),执行一些通用的错误处理并返回正确的响应类型。
我已经为此工作了代码,但我想知道是否有更优雅的方法来做到这一点。在泽西岛还有很多我不熟悉的事情,所以我很有可能错过了什么。
代码非常简单,并使用UriInfo注入来识别异常的来源。
My 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上运行,它可能最终导致一些令人讨厌的问题编辑:结果泽西规范不允许一个@Path拥有多个资源,因此如果处理得当(即找到正确的资源)就不会发生这种情况。不过,我发现这不是一个令人满意的解决方案。
解决问题的一个更优雅的方法是以某种方式将NotFoundExceptionMapper_ThatReturnsResponseTypeA直接关联到ClassA,将另一个NotFoundExceptionMapper_ThatReturnsResponseTypeB关联到ClassB。但是,我还没有找到任何办法。
有办法吗?