方法级别约束验证器未执行

我正在Spring REST Controller类中进行验证。如果参数对象本身发生约束冲突,则不会执行我的自定义约束验证器。

期望

请求

{
  fieldA: "2020-01-05",fieldB: "2020-01-02",fieldC: ""
}

响应:

{
  errors: [
    "Field C is mandatory","Invalid date range"
  ]
}

当前-场景1

请求

{
  fieldA: "2020-01-05",fieldC: ""
}

响应:

{
  errors: [
    "Field C is mandatory"
  ]
}

当前-方案2

请求

{
  fieldA: "2020-01-05",fieldC: "<some-value>"
}

响应:

{
  errors: [
    "Invalid date range."
  ]
}

这是代码段

SomeAPI.java

@RestController
@RequestMapping(value = "/")
@Validated
public class SomeAPI {

    @PostMapping
    @SomeValidation
    public ResponseEntity<Map<String,Object>> saveSomething(@Valid @RequestBody SomeForm form) {
        return new ResponseEntity<>(responseBody,HttpStatus.CREATED);
    }

}

SomeForm.java

public class SomeForm {

  @NotNull(message = "Field A is mandatory")
    private LocalDate fieldA;

  @NotNull(message = "Field B is mandatory")
    private LocalDate fieldB;

  @NotBlank(message = "Field C is mandatory")
    private String fieldC;

  // Setters and getters

}

SomeValidation.java

@Documented
@Constraint(validatedBy = SomeValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface SomeValidation {

  String message() default "";

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};

}

@SupportedValidationTarget(ValidationTarget.PARAMETERS)
class SomeValidator implements ConstraintValidator<SomeValidation,Object[]> {

  private static Logger logger = LoggerFactory.getLogger(SomeValidator.class);

  @Override
  public boolean isValid(Object[] value,ConstraintValidatorContext context) {
    context.disableDefaultConstraintViolation();
    SomeForm form = (SomeForm) value[0];
    boolean valid = true;
    if (!isValid(form)) {
      valid = false;
      context.buildConstraintViolationWithTemplate("Invalid date range").addConstraintViolation();
    }
    return valid;
  }

  private boolean isValid(SomeForm form) {
    logger.info("isValid");
    return form.getFieldA().isBefore(form.getFieldB());
  }

}

APIExceptionHandler.java

@ControllerAdvice
public class APIExceptionHandler extends ResponseEntityExceptionHandler {

    private static final String TIMESTAMP_KEY = "timestamp";
    private static final String STATUS_KEY = "status";
    private static final String ERRORS_KEY = "errors";

    @Override
    protected ResponseEntity<Object> handleBindException(BindException ex,HttpHeaders headers,HttpStatus status,WebRequest request) {
        Map<String,Object> body = new LinkedHashMap<>();
        body.put(TIMESTAMP_KEY,new Date());
        body.put(STATUS_KEY,status.value());
        List<String> errors = ex.getBindingResult().getFieldErrors().stream().map(FieldError::getDefaultMessage)
                .collect(Collectors.toList());
        body.put(ERRORS_KEY,errors);
        return new ResponseEntity<>(body,headers,status);
    }

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,status.value());
        List<String> errors = ex.getBindingResult().getallErrors().stream().map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        body.put(ERRORS_KEY,status);
    }

    @ExceptionHandler({ ConstraintViolationException.class })
    public ResponseEntity<Object> handleConstraintViolation(final ConstraintViolationException ex,final WebRequest request) {
        Map<String,HttpStatus.BAD_REQUEST.value());
        List<String> errors = ex.getconstraintViolations().stream().map(ConstraintViolation::getMessage)
                .collect(Collectors.toList());
        body.put(ERRORS_KEY,new HttpHeaders(),HttpStatus.BAD_REQUEST);
    }

}
lgxiaoshu 回答:方法级别约束验证器未执行

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/2815162.html

大家都在问