【问题标题】:Jersey: A generic catch all handler for errors?Jersey:一个通用的 catch all 错误处理程序?
【发布时间】:2013-10-23 15:19:26
【问题描述】:

Jersey 支持将 ExceptionMappers 作为一般处理坏事的一种方式,但这仅在调用到达我的代码时才有效。如果有人喜欢这个 URL,比如 http://host/fubar 而不是 http://host/foobar,那么它会返回一个通用的 404。

我需要获取那些经过优化的 URL 并重定向到我选择的页面,但几个小时后我似乎无法找到正确的配置来实现这一点。我一直在浏览调试器,但我没有找到可以挂接某些配置以将此类 404 重定向到我选择的页面的位置。

编辑:请注意,任何 WebApplicationException 的自定义异常映射器都会被 Jersey (1.17.1) 忽略。相反,它被路由到不同的处理方法。这是 Jersey 的 ContainerResponse.java 中的代码 sn-p:

if (cause instanceof WebApplicationException) {
    mapWebApplicationException((WebApplicationException)cause);
} else if (!mapException(cause)) { ... }

那 mapWebApplicationException((WebApplicationException)cause) 是 Jersey 自己处理的,所以它永远不会遇到调用自定义映射器的 elseif 中的 mapException(cause) 方法。

【问题讨论】:

    标签: java jersey


    【解决方案1】:

    解决赏金问题:

    这可能是 Jersey 中的一个错误,因为处理异常的公认方法不适用于 WebApplicationException。我正在寻找解决方法、错误报告或在更高版本中修复的信息。

    您可以创建一个捕获RuntimeExceptionExceptionMapper,然后测试异常是否为WebApplicationException 的实例:

    @Provider
    public class CustomExceptionMapper implements ExceptionMapper<RuntimeException> {
    
        @Override
        public Response toResponse(RuntimeException e) {
    
            if (e instanceof WebApplicationException) {
                return ((WebApplicationException) e).getResponse();
            }
    
            return Response.serverError().build();
        }
    }
    

    【讨论】:

    • 这应该可以工作,我们会捕获这样的所有内容,如果有人抛出 Web 应用程序异常,则会记录一个严重错误。
    • 这仍然无法通过我提到的 ContainerResponse.java 代码。一个经过优化的 URL 永远不会到达我的异常映射器,因为经过优化的 URL 是一个 WebApplicationException,它在 ContainerResponse 的第一个“if”子句中被捕获,因此它永远不会进入第二个 else-if 块,这是我的自定义异常映射器将被调用的地方.我能想出的唯一解决方案是让我的服务器上的每个请求都暴露一个 /* REST 端点,然后从那里进行内部路由,然后绕过 jaxws 提供的所有漂亮的@PATH 东西:(
    • @ChrisKessel 至少在 Jersey 2.x 中已经修复了这种行为。
    • @CássioMazzochiMolin 您使用的是什么版本的球衣?他们是否修复了 OP 在该版本中提到的错误?
    • @JonRomero 我用过很多版本的泽西岛。我建议您尽可能使用最新版本。当前版本是 2.25.x,我在答案中发布的代码在该版本中运行良好。
    【解决方案2】:

    创建一个 customExceptionMapper 应该可以解决这个问题。

    @Provider
    public class NotFoundMapper implements ExceptionMapper<NotFoundException>{
    
     public Response toResponse(NotFoundException exception){
    
        // do your custom processing here..
     }
    
    }
    

    【讨论】:

    • 很遗憾,没有。不会为任何 WebApplicationException 调用自定义映射器。 ContainerResponse.mapMappableContainerException,第 398 行(版本 1.17.1),首先查找该案例并转移到它自己的处理程序。只有当它是某种其他类型的异常时,它才会查找映射的异常。
    【解决方案3】:

    尝试使用 jersey2.version =2.19 并且它工作不知道 abt 1+ 版本

    演示网址:https://jerseyexample-ravikant.rhcloud.com/rest/jws/getUserList/

    您可以将其更改为其他任何内容,并且会出现以下错误消息

        @Provider
    public class EntityNotFoundException  extends WebApplicationException implements ExceptionMapper<NotFoundException>
    { 
    
        private static final long serialVersionUID = 7886520141629139380L;
    
        //@Override
        public Response toResponse(NotFoundException arg0) {
    
            StringBuilder response = new StringBuilder("<response>");
            response.append("<status>ERROR</status>");
            response.append("<message>The method you are looking for does not exist </message>");
            response.append("<time>" + new Date().toString() + "</time>");
            response.append("</response>"); 
            return Response.status(404).entity(response.toString()).type(MediaType.APPLICATION_XML).build();
        }
    
    
    }
    

    【讨论】:

    • 您的ExceptionMapper 本身无需成为Exception。所以你可以去掉extends WebApplicationException,最好把它从EntityNotFoundException重命名为NotFoundExceptionMapper
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 2019-05-19
    • 2013-01-21
    • 1970-01-01
    相关资源
    最近更新 更多