我有这样的控制器处理程序:
@RequestMapping(method = POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ApiOperation(value = "Add to basket")
@ApiResponses(value = {@ApiResponse(code = 200, message = "Successfully add to basket")})
@PreAuthorize("@securityService.hasUserAccess()")
public ResponseEntity addToBasket(@RequestBody @ItemAlreadyExistInBasket ProductEntity product) {
basketService.addToBasket(product);
return new ResponseEntity(HttpStatus.OK);
}
思考是注释
@ItemAlreadyExistInBasket
永远不会被触发,我不知道为什么。这是我使用约束验证的注释
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = ItemAlreadyExistInBasketConstraint.class)
public @interface ItemAlreadyExistInBasket {
String message() default "Item already exist in basket";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class ItemAlreadyExistInBasketConstraint implements ConstraintValidator<ItemAlreadyExistInBasket, ProductEntity> {
@Autowired
private BasketRepository basketRepository;
@Autowired
private UserRepository userRepository;
@Override
public void initialize(ItemAlreadyExistInBasket constraintAnnotation) {
}
@Override
public boolean isValid(ProductEntity productEntity, ConstraintValidatorContext context) {
userRepository.findByLogin(UserUtil.getAuthenticatedUserName());
return basketRepository.findByUserAndStatusAndProduct(userRepository.findByLogin(UserUtil.getAuthenticatedUserName()), Status.ACTIVE, productEntity).isEmpty();
}
}
有什么想法吗?
答案 0 :(得分:3)
我最近也不得不处理这些方法验证,不知道你是否已经找到了这个问题的答案,但我仍然会回答这个问题。以下适用于Spring 4.1.2(也可能是早期版本)
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
@RestController
@Validated
[...]
public class YourController ...
就像您在问题中发布的那样,您可以使用JSR303规范实现验证器。
不知何故,当使用@Value和方法验证时,Spring会以不同的方式处理验证错误。因此,如果您希望您的方法返回400错误而不是抛出服务器异常,您还需要实现类似于此方法的内容:
/**
* Handle Constraint exceptions in order to return a bad request http status
*/
@ExceptionHandler(value = { ConstraintViolationException.class })
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public String handleResourceNotFoundException(ConstraintViolationException e) {
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
StringBuilder strBuilder = new StringBuilder();
for (ConstraintViolation<?> violation : violations ) {
strBuilder.append(violation.getMessage() + "\n");
}
return strBuilder.toString();
}
奇怪的是,我不得不将此方法放在我的RestController中。我在@Configuration类中测试了它的实现,但它没有用。
如果您同时需要POJO验证和方法参数验证,请在类级别使用@Validated注释,在方法上使用POJO之前使用@Valid。使用@Valid注释时,将在此POJO中声明的所有内容(例如字段上的@NotNull)也将得到验证。这是我必须实现的用例。
希望这有帮助!