这通常是一个很好的例子
bean validation
.虽然已经有许多验证案例的内置支持(
@Size
,
@NotNull
, ...), 还可以编写自己的自定义约束。
首先,您需要定义一个注释来验证您的ID,例如:
@Documented
@Constraint(validatedBy = OrderIdValidator.class)
@Target({PARAMETER})
@Retention(RUNTIME)
public @interface ValidOrderId {
String message() default "Invalid order ID";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
由于订单ID始终是控制器映射的参数,因此可以使用
ElementType.PARAMETER
仅允许对方法参数进行注释。
下一步是添加
@Constraint
注释并指向一个定制的验证器类(例如。
OrderIdValidator
):
@Component
public class OrderIdValidator implements ConstraintValidator<ValidOrderId, Integer> {
private OrderRepository repository;
public OrderIdValidator(OrderRepository repository) {
this.repository = repository;
}
@Override
public boolean isValid(Integer id, ConstraintValidatorContext constraintValidatorContext) {
return repository.existsById(id);
}
}
通过实施
isValid
方法,您可以检查订单是否存在。如果它不存在,将抛出一个异常,然后
message()
财产
@ValidOrderId
注释将用作消息。
最后一步是添加
@Validated
注释到所有控制器,并添加
@瓦利多德里德
所有订单ID参数的注释,例如:
@Validated // Add this
@RestController
public class OrderController {
@GetMapping("order/{id}")
public Order getCustomer(@PathVariable @ValidOrderId final Integer id) { // Add @ValidOrderId
// Do stuff
}
}
如果您更喜欢在验证中使用不同的响应状态,那么可以添加一个带有
@ControllerAdvice
注释并使用以下方法:
@ExceptionHandler(ConstraintViolationException.class)
public void handleConstraints(HttpServletResponse response) throws IOException {
response.sendError(HttpStatus.BAD_REQUEST.value());
}