我有一个名为 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 中的方法不同的响应类型。
ExceptionMapper 似乎是避免冗余错误处理代码的好方法。剩下要做的就是确定异常来自哪里(ClassA 或 ClassB),执行一些通用错误处理并返回正确的响应类型。
我已经为此工作了代码,但我想知道是否有更优雅的方式来做到这一点。泽西岛还有很多我不熟悉的东西,所以我很有可能错过了一些东西。
代码相当简单,并使用 UriInfo 注入来识别异常的来源。
我的异常映射器:
@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。不过,我还没有找到任何方法。
有办法吗?