Sring 3 完全支持JSR-303 Bean的验证API,当编程使用验证时,Spring的DataBinder可以验证对象并绑定他们,最后Spring MVC现在支持在@COntroller中输入验证内容。
例子:
1.编写VO对象并设置验证规则
package com.test.entity.vo;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* @Author:qmfang
* @Description:
* @Date:Created in 12:21 2018/4/11
* @Modified By:
*/
@Data
public class MyModel {
@NotNull
@Size(max=64)
private String name;
@Min(0)
private int age;
}2.配置bean Validation提供者 Spring boot好像默认就提供了,不需要此步骤
/**
*
* 触发bean验证使用默认的引导机制进行初始化
* JSR-303/JSR-349提供程序(如Hibernate-Validator)需要放到类路径下,
* 以便能被自动检测。
*
* @return
*/
@Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}3.创建验证类
@Service
public class MyService {
@Autowired
private Validator validator;
public <T> void validate(T entity, Class<?>... groups) {
Set<ConstraintViolation<T>> constraintViolations = validator.validate(entity, groups);
if (constraintViolations.isEmpty()) {
return;
}
ConstraintViolation<T> first = constraintViolations.iterator().next();
throw new RuntimeException(first.getMessage());
}
}4.对VO对象进行校验
@Autowired
private MyService myService;
/**
* 127.0.0.1:8886/get3?name=shijieheping&age=-1
*
* @return
*/
@GetMapping(value = "/get3")
public Object get(MyModel myModel) throws IOException {
myService.validate(myModel);
return myModel;
}这样使用起来有点麻烦,需要注入校验对象,采用如下形式会跟方便一点。这样使用时就不需要在使用注入的形式了,同时也可以去掉步骤2.配置bean Validation提供者 因为下面的类在static{}快中自行构建了
public class MyService {
private static final Validator validator;
static {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
public static <T> void validate(T entity, Class<?>... groups) {
Set<ConstraintViolation<T>> constraintViolations = validator.validate(entity, groups);
if (constraintViolations.isEmpty()) {
return;
}
ConstraintViolation<T> first = constraintViolations.iterator().next();
throw new RuntimeException(first.getMessage());
}
}配置自定义约束
每个bean验证约束都由两部分组成,首先是申明约束及其可配置的@Constraint注解,然后是实现约束行为的javax.validation.ConstraintValidator接口实现,如果要将声明与实现关联,每个@Constraint注解都会应用相应的ValidationConstranit实现类,在运行中,当在域模型中遇到约束注解时,ConstranitValidatorFactory会将应用的实现实例化。
默认情况下,LocalValidatorFactoryBean会配置SpringConstraintValidatorFactory,他会使用Spring去创建ConstranitValidator实例,这允许自定义ConstranitValidators,就像任何其他Spring Bean一样,从依赖注入中获利。
1.编写相应的注解 以及校验实现类 注意就是NameCheck时可以在外部定义,通过@Component 来使用@Autowried注解的
import org.springframework.util.StringUtils;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* @Author:qmfang
* @Description:
* @Date:Created in 15:10 2018/4/11
* @Modified By:
*/
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {Name.NameCheck.class})
public @interface Name {
/**
* 使用该消息进行提示
*
* @return
*/
String message() default "名字不能为空";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
class NameCheck implements ConstraintValidator<Name, String> {
@Override
public void initialize(Name name) {
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
return StringUtils.isEmpty(s);
}
}
}2.编写测试用例
import com.test.config.Name;
import lombok.Data;
import javax.validation.constraints.Min;
/**
* @Author:qmfang
* @Description:
* @Date:Created in 12:21 2018/4/11
* @Modified By:
*/
@Data
public class MyModel {
@Name
private String name;
@Min(0)
private int age;
} @GetMapping(value = "/get3")
public Object get(MyModel myModel) throws IOException {
MyService.validate(myModel);
return myModel;
}即可。Spring 驱动的方法验证
Bean Validation1.1支持方法验证 Hibernate Validator 4.3支持的自定义扩展也可以通过MethodValidationPostProcessor bean定义继承到Spring上下文中。
Spring boot默认的注册了MethodValidationPostProcessor
当然也可以手动注册,已追加扩展
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}然后在类上使用@Validated注解如下
@Validated
@RestController
public class TestController {
/**
* 127.0.0.1:8886/get3?name=shijieheping&age=-1
*
* @return
*/
@GetMapping(value = "/get3")
public Object get(@Length(min = 10) String name) throws IOException {
System.out.println(name);
return name;
}
}这样就可以针对单个参数进行校验了。注意点就是 此注解对于非controller类的方法没有效果。
配置DataBinder
从Spring 3开始,可以使用Validator配置DataBinder实例,配置后,可以通过调用binder.validate()方法使用,任何验证错误都可以自动加入到binder的BindingResult中。
在以编程的方式使用DataBinder时,可以在绑定到目标对象后调用验证逻辑。
DataBinder还可以通过DataBinderaddValidators和replaceValidators来配置多个Validator实例,将全局配置的Bean Validation与本地在DataBinder实例上配置的Spring Validator相结合,能够发挥强大的威力。
本文介绍了如何在 Spring MVC 应用中使用 JSR-303 进行数据验证,包括自定义验证注解、配置验证提供者以及方法级验证等实践案例。
434

被折叠的 条评论
为什么被折叠?



