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>
,它可以处理所有错误。然后您可以创建更具体的 ExceptionMapper
s 以另一种方式处理更具体的错误。所有这些都在单独的 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);
}
}
我有一个 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>
,它可以处理所有错误。然后您可以创建更具体的 ExceptionMapper
s 以另一种方式处理更具体的错误。所有这些都在单独的 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);
}
}