我正在使用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{}
}
然后在控制器中调用它:
public String saveAccount(@ModelAttribute @Validated({Account.Step1.class}) Account account, BindingResult result) {
//some more code and stuff here
return "";
}
但我想根据控制器方法中的某些逻辑来决定使用的组。有没有办法手动调用验证?像result = account.validate(Account.Step1.class)
?
我知道创建自己的Validator类,但这是我想要避免的,我宁愿只使用类变量本身的注释。
答案 0 :(得分:37)
在答案中比 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 "";
}
答案 1 :(得分:18)
以下是JSR 303 spec
的代码示例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 );
所以是的,您可以从验证器工厂获取验证器实例并自行运行验证,然后检查是否存在违规。您可以在javadoc for Validator中看到它还将接受一组要验证的组。
显然,这直接使用JSR-303验证而不是通过Spring验证,但我相信如果在类路径中找到弹簧验证注释将使用JSR-303
答案 2 :(得分:7)
如果您已正确配置所有内容,则可以执行以下操作:
@Autowired
Validator validator;
然后你可以用它来验证你的对象。
答案 3 :(得分:2)
此链接提供了在Spring应用程序中使用验证的很好的示例。 https://reflectoring.io/bean-validation-with-spring-boot/
在本文中,我找到了一个以编程方式运行验证的示例。
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);
}
}
}
它将抛出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);
}
}
第二个示例来自https://www.mkyong.com/spring-boot/spring-rest-error-handling-example/
更新: 不建议使用验证为持久层: https://twitter.com/odrotbohm/status/1055015506326052865
答案 4 :(得分:1)
还有:
ViewStub
答案 5 :(得分:1)
除了@digitaljoel的回答,一旦发现违规情况,您就可以抛出ConstraintViolationException。
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<NotionalProviderPaymentDTO>> violations = validator.validate( notionalProviderPaymentDTO );
if(!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
您可以创建自己的异常映射器,该映射器将处理ConstraintViolationException并将错误消息发送给客户端。
答案 6 :(得分:0)
import javax.validation.Validator;
import javax.validation.ConstraintViolation;
public class{
@Autowired
private Validator validator;
.
.
public void validateEmployee(Employee employee){
Set<ConstraintViolation<Employee>> violations = validator.validate(employee);
if(!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
}
这里,'Employee' 是一个 pojo 类,'employee' 是它的对象