Exception handling ExceptionMapper未处理转换器异常

Exception handling ExceptionMapper未处理转换器异常,exception-handling,jersey,jax-rs,jersey-2.0,Exception Handling,Jersey,Jax Rs,Jersey 2.0,根据标题,ParamConverter引发的异常没有按我预期的方式处理 除此之外,还有一个例外: @Provider public class MyExceptionMapper implements ExceptionMapper<MyException> { @Override public Response toResponse(MyException exception) { return Response.serverError().enti

根据标题,ParamConverter引发的异常没有按我预期的方式处理

除此之外,还有一个例外:

@Provider
public class MyExceptionMapper implements ExceptionMapper<MyException> {
    @Override
    public Response toResponse(MyException exception) {
        return Response.serverError().entity( "It triggered" ).build();
    }
}
它不会在500错误中返回“It triggered”文本,而是返回404

预期问题:两个提供商都注册了吗

是-如果我从资源(在“常规”代码中)抛出“MyException”,它将按预期工作。我还可以看到带有“convert”消息的stacktrace

有没有办法让ExceptionMapper处理来自ParamConverter的异常

我正在使用jersey 2.3.1以及spring jersey,它是在jetty容器9.1.0中启动的。RC0从阅读来看,JAX-RS规范说实现者应该将未处理的异常包装在
@QueryParam
@PathParam
NotFoundException
(404)中,根据我测试的400,(我猜是
@FormParam
BadRequestException

如果字段或属性用
@MatrixParam
@QueryParam
@PathParam
注释,则实现必须生成
NotFoundException
(404状态),它包装抛出的异常而不包含实体”

我可以看到处理异常的两种方法是

  • 只需在
    参数转换器
    中处理它,例如

    return new ParamConverter<T>() {
    
        @Override
        public T fromString(String string) {
            try {
                return (T)new MyObject().setValue(string);
            } catch (MyException ex) {
                Response response = Response.serverError().entity("Boo").build()
                throw new WebApplicationException(response);
            }
        }
    
        @Override
        public String toString(T t) {
            return t.toString();
        }  
    };
    

  • 我在泽西2.26也经历过同样的行为

    任何扩展RuntimeException的异常都会映射到ParameterException,它本身就是WebApplicationException的子类。 假设您的MyException扩展了RuntimeException,它不会被捕获,因为您的ExceptionApper只处理MyException

    关于Jersey文档说抛出NotFoundException:我认为404在queryParam无法转换时不适用。BadRequestException似乎更合适。而且,除了设置响应代码外,我看不到在抛出NotFoundException时Jersey框架中有什么独特之处

    要让ParamConverter抛出的异常最终出现在ExceptionMapper中,您必须让ExceptionMapper捕获更全局的异常,如Throwable


    另一个答案建议返回WebApplicationException。这应该是一个很好的解决方案,但如果响应对象有实体,它将不起作用。请参见此处:

    我必须说,我对这种行为感到非常惊讶,但最终它对我来说是有意义的。查询参数是URL的一部分,它们无法解析,URL无效。我们将日期(YYYY-MM-DD)解析为查询参数的问题。在我们的自定义查询参数转换器中,我们抛出了一个
    DateTImeParseException
    ,它实际上被包装到了NotFoundException中。为了解决“问题”,我们现在抛出了一个自定义异常,该异常使用自定义映射器从WebApplicationException继承。:)
    return new ParamConverter<T>() {
    
        @Override
        public T fromString(String string) {
            try {
                return (T)new MyObject().setValue(string);
            } catch (MyException ex) {
                Response response = Response.serverError().entity("Boo").build()
                throw new WebApplicationException(response);
            }
        }
    
        @Override
        public String toString(T t) {
            return t.toString();
        }  
    };
    
    public class MyException extends WebApplicationException {
    
        public MyException(String message) {
            super(Response.serverError().entity(message).build());
        }
    }