JAX-RS(球衣实现)ExceptionMapper<Throwable> 没有捕获 ConstraintViolationException

JAX-RS (jersey implementation) ExceptionMapper<Throwable> aren't catching ConstraintViolationException

我有一个 ExceptionMapper 作为 @Provider 来处理我所有的异常。

所以很明显,我的 class 实现了 ExceptionMapper<Throwable> 并且我们知道,所有异常都以某种方式扩展 Throwable

现在我使用 jax-rs @NotNull 检查我的资源输入值是否为空,通过一些搜索,我意识到当注释字段为空时它会抛出 ConstraintViolationException

所以我尝试处理它并在我的 ExceptionMapper 中添加一些响应细节(添加一些自定义 json 模型),如下所示:

@Provider
public class AllExceptionMapper implements ExceptionMapper<Throwable> {

    private final Logger logger = LogManager.getLogger(AllExceptionMapper.class);

    @Override
    public Response toResponse(Throwable ex) {
        Response response;
        CustomError error;
        // handle some errors

        else if (ex instanceof ConstraintViolationException) {
             error = new CustomError(
                 324, // predefined error type in our documents
                 "some details"
             );
             response = Response.status(Response.Status.BAD_REQUEST).entity(error).build();
        }

        // handle some other errors

        return response;
    }

}

问题是这不起作用,但如果我创建另一个实现ExceptionMapper<ConstraintViolationException> 的异常映射器提供程序并在那里处理它,它就可以正常工作。

正如我之前所说(并检查过)所有异常都是从 Throwable class 以某种方式扩展的,所以我缺少什么以及为什么它不起作用?

......

无效,我的意思是它忽略了我的映射器(从 ExceptionMapper<Throwable> 实现的映射器)并具有正常行为,即返回状态代码 400,没有响应负载,就像没有映射器一样完全

ExceptionMapper 的工作方式是您可以创建一个通用的 ExceptionMapper<Throwable>,它可以处理所有错误。然后您可以创建更具体的 ExceptionMappers 以另一种方式处理更具体的错误。所有这些都在单独的 classes 中。

事实上,在单独的 class 中执行此操作对您有用,这让我相信在某个地方有更具体的 ExceptionMapper,它可以在您之前处理异常。

ExceptionMappers 的使用方式实际上是非常干净的,而且还能保持您的代码干净。想要将代码放在一个中心位置,将导致巨大的 if...

不要使用 @Privider,应该使用 'ResourceConfig.register(MyExceptionMapper);'

 public class ErrorHandler implements ExceptionMapper<Throwable> {

    private final static Logger LOGGER = LoggerFactory.getLogger(ErrorHandler.class);

    @Override
    public Response toResponse(Throwable e) {

        LOGGER.error("Handle a unknown error, " + e.getClass() + ": " + e.getMessage(), e);
        e.printStackTrace();

        Response.ResponseBuilder responseBuilder = Response.status(status);
        responseBuilder.entity(exception);

        return responseBuilder.build();
    }
}


class Config extends ResourceConfig {

    private final static Logger LOGGER = LoggerFactory.getLogger(Main.class);

    public Config() {
        super();
        super.register(ErrorHandler.class);
    }
}