Java 手动调用 Spring Annotation Validation
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19190592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Manually call Spring Annotation Validation
提问by Ross Hettel
I'm doing a lot of our validation with Hibernate and Spring Annotations like so:
我正在使用 Hibernate 和 Spring Annotations 进行很多验证,如下所示:
public class Account {
@NotEmpty(groups = {Step1.class, Step2.class})
private String name;
@NotNull(groups = {Step2.class})
private Long accountNumber;
public interface Step1{}
public interface Step2{}
}
And then in the controller it's called in the arguments:
然后在控制器中,它在参数中被调用:
public String saveAccount(@ModelAttribute @Validated({Account.Step1.class}) Account account, BindingResult result) {
//some more code and stuff here
return "";
}
But I would like to decide the group used based on some logic in the controller method. Is there a way to call validation manually? Something like result = account.validate(Account.Step1.class)
?
但我想根据控制器方法中的一些逻辑来决定使用的组。有没有办法手动调用验证?像result = account.validate(Account.Step1.class)
什么?
I am aware of creating your own Validator class, but that's something I want to avoid, I would prefer to just use the annotations on the class variables themselves.
我知道创建您自己的 Validator 类,但这是我想避免的,我宁愿只使用类变量本身的注释。
采纳答案by Pavel Horal
Going a step further than Jaiwo99in his answer:
在他的回答中比Jaiwo99更进一步:
// org.springframework.validation.SmartValidator - implemented by
// LocalValidatorFactoryBean, which is funny as it is not a FactoryBean per se (just saying)
@Autowired
SmartValidator validator;
public String saveAccount(@ModelAttribute Account account, BindingResult result) {
// ... custom logic
validator.validate(account, result, Account.Step1.class);
if (result.hasErrors()) {
// ... on binding or validation errors
} else {
// ... on no errors
}
return "";
}
And the mandatory link to SmartValidator JavaDocif you are interested.
如果您有兴趣,还有指向 SmartValidator JavaDoc的强制性链接。
回答by digitaljoel
Here is a code sample from JSR 303 spec
这是JSR 303 规范中的代码示例
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Driver driver = new Driver();
driver.setAge(16);
Car porsche = new Car();
driver.setCar(porsche);
Set<ConstraintViolation<Driver>> violations = validator.validate( driver );
So yes, you can just get a validator instance from the validator factory and run the validation yourself, then check to see if there are violations or not. You can see in the javadoc for Validatorthat it will also accept an array of groups to validate against.
所以是的,你可以从验证器工厂获取一个验证器实例并自己运行验证,然后检查是否存在违规。您可以在Validator的javadoc 中看到它也将接受一组要验证的组。
Obviously this uses JSR-303 validation directly instead of going through Spring validation, but I believe spring validation annotations will use JSR-303 if it's found in the classpath
显然这直接使用 JSR-303 验证而不是通过 Spring 验证,但我相信如果在类路径中找到了 JSR-303,那么我相信 Spring 验证注释将使用 JSR-303
回答by Jaiwo99
If you have everything correctly configured, you can do this:
如果您已正确配置所有内容,则可以执行以下操作:
@Autowired
Validator validator;
Then you can use it to validate you object.
然后您可以使用它来验证您的对象。
回答by supercobra
And also:
并且:
@Autowired
@Qualifier("mvcValidator")
Validator validator;
...
violations = validator.validate(account);
回答by Prabjot Singh
Adding to answered by @digitaljoel, you can throw the ConstraintViolationException once you got the set of violations.
除了@digitaljoel 的回答之外,您可以在获得一组违规后抛出 ConstraintViolationException。
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<NotionalProviderPaymentDTO>> violations = validator.validate( notionalProviderPaymentDTO );
if(!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
You can create your own exception mapper which will handle ConstraintViolationException and send the errors messages to the client.
您可以创建自己的异常映射器,它将处理 ConstraintViolationException 并将错误消息发送到客户端。
回答by Sarvar Nishonboev
This link gives pretty good examples of using validations in Spring apps. https://reflectoring.io/bean-validation-with-spring-boot/
此链接提供了在 Spring 应用程序中使用验证的很好示例。 https://reflectoring.io/bean-validation-with-spring-boot/
I have found an example to run the validation programmitically in this article.
我在本文中找到了一个以编程方式运行验证的示例。
class MyValidatingService {
void validatePerson(Person person) {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Person>> violations = validator.validate(person);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
}
It throws 500
status, so it is recommended to handle it with custom exception handler.
它抛出500
状态,因此建议使用自定义异常处理程序来处理它。
@ControllerAdvice(annotations = RestController.class)
public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<CustomErrorResponse> constraintViolationException(HttpServletResponse response, Exception ex) throws IOException {
CustomErrorResponse errorResponse = new CustomErrorResponse();
errorResponse.setTimestamp(LocalDateTime.now());
errorResponse.setStatus(HttpStatus.BAD_REQUEST.value());
errorResponse.setError(HttpStatus.BAD_REQUEST.getReasonPhrase());
errorResponse.setMessage(ex.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
}
Second example is from https://www.mkyong.com/spring-boot/spring-rest-error-handling-example/
第二个例子来自https://www.mkyong.com/spring-boot/spring-rest-error-handling-example/
Update: Using validation is persistence layer is not recommended: https://twitter.com/odrotbohm/status/1055015506326052865
更新:不推荐使用验证是持久层:https: //twitter.com/odrotbohm/status/1055015506326052865