让ExceptionMapper根据异常来自

时间:2015-09-02 14:37:13

标签: java rest jersey response exceptionmapper

我有一个名为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。但是,我还没有找到任何办法。

有办法吗?

0 个答案:

没有答案