从Validator抛出的异常400被重新包装到http代码500的另一个异常中

时间:2016-07-20 09:32:29

标签: java annotations tomcat7 jax-rs bean-validation

我为JAX-RS查询参数和验证器编写了一个注释。 代码在预期时执行。

目标是在缺少查询参数的情况下发送选定的状态代码,如400。 泽西岛默认发送404不适合。

如果从端点抛出异常,则确定:客户端收到400错误。

如果从验证程序抛出WebApplicationException,它将被重新包装为500错误。

我可以在我的端点的父类中滚动一个方法,在每个端点的开头执行w /强制参数,但我宁愿通过使用注释来保持一致性。

问:如何将我的注释异常原样发送给客户端?

我已经尝试过自定义的ExceptionMappers。 尽管使用@Provider和包添加到扫描列表中进行了注释,但它们并未使用。甚至ExceptionMapper< ConstraintViolationException>

环境

Maven,基于Spring的项目 泽西岛v2.23.1 okhttp 2.0.0和2.7.5 Tomcat 7.0.47和55 jersey-bean-validation正在使用中

BV_SEND_ERROR_IN_RESPONSE:是的 BV_DISABLE_VALIDATE_ON_EXECUTABLE_OVERRIDE_CHECK:true

注释

@Target({java.lang.annotation.ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy={MustExistValidator.class})
@ReportAsSingleViolation
@Documented
public @interface MustExist {...}

验证

@Provider
@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class MustExistValidator implements ConstraintValidator<MustExist, List<Integer>> {
...
@Override
public boolean isValid(List<Integer> integerList, ConstraintValidatorContext context)
{
  if (integerList == null || integerList.isEmpty()) {
     context.disableDefaultConstraintViolation();
  //         throw ResourceException.emptyParameter(field);  // custom Exception : a WebApplicationException w/ status 400  : becomes 500 (KO)

     Response.ResponseBuilder builder = Response.status(Response.Status.BAD_REQUEST);
     builder.entity("Missing 'indicators' query parameter.");
     Response response = builder.build();
     throw new WebApplicationException( ResourceException.emptyParameter(field), response);
 // This is to populate a cause. So that its not replaced. KO too (500).

  }
  return true;

}

1 个答案:

答案 0 :(得分:0)

好吧,我的解决方案符合“处理它并解决”的类别。

不幸的是,故意在注释的验证器中抛出的异常被jersey / tomcat包装。

所以我的解决方案是为包装的异常编写一个映射器。 得到原因并做必须做的事。

@Component
@Provider
public class ValidationExceptionMapper implements ExceptionMapper<ValidationException> {

   @Override
   public Response toResponse(ValidationException exception) {
       if (exception.getCause() != null
            && exception.getCause() instanceof WebApplicationException) {