如何手动触发弹簧validation?

当从json请求体创建时,POJO字段上的带注释的弹簧validation起作用。 但是,当我手动创建相同的对象(使用setter)并想要触发validation时,我不知道该怎么做。

这是Registration类,它具有可以构建对象的Builder内部类。 在构建方法中,我想触发弹簧validation。 请滚动到底部并检查Builder.build()和Builder.valiate()方法以查看当前实现。 我正在使用javax.validation.Validator来触发validation,但我更愿意在可能的情况下利用springvalidation。

package com.projcore.dao; import com.projcore.util.ToString; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.validation.ConstraintViolation; import javax.validation.Valid; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.constraints.Size; import java.util.List; import java.util.Set; /** * The data transfer object that contains the information of a Registration * and validation rules for attributes. */ @JsonIgnoreProperties(ignoreUnknown = true) public final class Registration { private static final Logger LOGGER = LoggerFactory.getLogger(Registration.class); private String id; @NotEmpty @Size(max = 255) private String messageId; @NotEmpty @Size(max = 255) private String version; @Size(max = 255) private String system; public Registration() { } private Registration(Builder builder) { this.id = builder.id; this.messageId = builder.messageId; this.version = builder.version; this.system = builder.system; } public static Builder getBuilder() { return new Builder(); } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getMessageId() { return messageId; } public void setMessageId(String messageId) { this.messageId = messageId; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public String getSystem() { return system; } public void setSystem(String system) { this.system = system; } @Override public String toString() { return ToString.create(this); } /** * Builder pattern makes the object easier to construct in one line. */ public static class Builder { private String id; private String messageId; private String version; private String system; private Builder() {} public Builder id(String id) { this.id = id; return this; } public Builder messageId(String messageId) { this.messageId = messageId; return this; } public Builder version(String version) { this.version = version; return this; } public Builder system(String system) { this.system = system; return this; } public Registration build() { Registration entry = new Registration(this); // *** Would like to trigger spring validation here *** Set violations = validate(entry); if (violations.isEmpty()) return entry; else throw new RuntimeException(violations.toString()); } private Set validate(Registration entry) { Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); Set<ConstraintViolation> constraintViolations = validator.validate(entry); return constraintViolations; } } } 

validation在这里工作正常:

 @RequestMapping(method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) Registration create(@RequestBody @Valid Registration registration) 

解:

删除了Registraion.Builder.validate()。 将Registraion.Builder.build()更新为:

  public Registration build() { Registration entry = new Registration(this); return (Registration) ValidatorUtil.validate(entry); } 

ValidationUtil.java

 package projcore.util; import com.ericsson.admcore.error.InvalidDataException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.Errors; import org.springframework.validation.beanvalidation.SpringValidatorAdapter; import javax.validation.Validation; import javax.validation.Validator; import java.util.Set; public class ValidatorUtil { private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorUtil.class); private static final Validator javaxValidator = Validation.buildDefaultValidatorFactory().getValidator(); private static final SpringValidatorAdapter validator = new SpringValidatorAdapter(javaxValidator); public static Object validate(Object entry) { Errors errors = new BeanPropertyBindingResult(entry, entry.getClass().getName()); validator.validate(entry, errors); if (errors == null || errors.getAllErrors().isEmpty()) return entry; else { LOGGER.error(errors.toString()); throw new InvalidDataException(errors.getAllErrors().toString(), errors); } } } 

InvalidDataException.java

 package projcore.error; import org.springframework.validation.Errors; /** * This exception is thrown when the dao has invalid data. */ public class InvalidDataException extends RuntimeException { private Errors errors; public InvalidDataException(String msg, Errors errors) { super(msg); setErrors(errors); } public Errors getErrors() { return errors; } public void setErrors(Errors errors) { this.errors = errors; } } 

Spring为JSR-303 Bean Validation API提供了完全支持。 这包括方便地支持将JSR-303实现引导为Spring bean。 这允许在应用程序中需要validation的任何地方注入javax.validation.Validator。

使用LocalValidatorFactoryBean将默认的JSR-303 Validator配置为Spring bean:

   

上面的基本配置将触发JSR-303使用其默认引导机制进行初始化。 JSR-303提供程序(如Hibernate Validator)应该出现在类路径中,并将自动检测。

5.7.2.1注入validation器

LocalValidatorFactoryBean implements both javax.validation.Validator and org.springframework.validation.Validator. 您可以将对这两个接口之一的引用注入需要调用validation逻辑的bean中。

如果您希望直接使用JSR-303 API,请注入对javax.validation.Validator的引用:

 // JSR-303 Validator import javax.validation.Validator; @Service public class MyService { @Autowired private Validator validator; } 

如果您的bean需要Spring Validation API,则引用对org.springframework.validation.Validator的引用:

 // Spring Validator import org.springframework.validation.Validator; @Service public class MyService { @Autowired private Validator validator; } 

这是一个很好的例子, 使用JSR 303和“经典”Spring Validators(输入SpringValidatorAdapter)

这个链接非常有用。 在org.springframework.validation.beanvalidation.SpringValidatorAdapter中包装javax.validation.Validator有助于一致地处理错误。 你可以添加这个作为答案,以便我可以接受它

和Spring doc在这里