校验实践
前提
SpringBoot+web
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
修改实体类
package com.example.springbootvalidator.entity;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author CBeann
* @create 2020-01-11 16:01
*/
@Data//lombok注解
public class Student {
private Integer id;
@NotBlank(message = "name不能为空")
private String name;
//@NotBlank(message = "name不能为空")//会报错
@NotNull(message = "age不能为空")
private Integer age;
@NotBlank(message = "email不能为空")
@Email(message = "邮箱不合法")
private String email;
}
控制层
@RequestMapping("/hello")
public String hello(@Valid Student student,//实体类前面加@Valid,异常信息存在BindingResult result中
BindingResult result) {
List<String> list = new ArrayList<>();
if (result.hasErrors()) {
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError allError : allErrors) {
list.add(allError.getDefaultMessage());
}
}
return list.toString();
}
请求及请求结果
校验模式
如上图所示,默认会校验完所有属性,然后将错误信息一起返回,但很多时候不需要这样,一个校验失败了,其它就不必校验了
package com.example.springbootvalidator.config;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
/**
* @author CBeann
* @create 2020-01-11 19:00
*/
@Configuration
public class Configulation {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
}
测试如下
自定义校验规则
前提
上面的 校验实践 的基础之上进行
需求
验证sex性别参数是否合法,添加自己定义的校验注解进行校验
实践
自定义的属性注解
package com.example.springbootvalidator.myvalidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* @author CBeann
* @create 2020-01-11 20:25
*/
@Target({ElementType.FIELD})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = SexValidator.class)//关联校验规则
public @interface SexAnnotation {
String message() default "sex参数错误";
//下面这两个属性必须添加
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
自定义的属性校验规则
package com.example.springbootvalidator.myvalidator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class SexValidator implements ConstraintValidator<SexAnnotation, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
//符合条件
if ("男".equals(value) || "女".equals(value)) {
return true;
} else {
//禁用默认的message的值,否则它会出现两条信息:一条是SexAnnotation中message属性的默认消息,一条是下面“不男不女”的消息
context.disableDefaultConstraintViolation();
//重新添加错误提示语句
context.buildConstraintViolationWithTemplate("不男不女").addConstraintViolation();
return false;
}
}
}
实体类
package com.example.springbootvalidator.myvalidator;
import lombok.Data;
/**
* @author CBeann
* @create 2020-01-11 20:31
*/
@Data//lombok注解
public class Person {
@SexAnnotation//自定义的校验规则
private String sex;//性别
}
控制层
@RequestMapping("/hello2")
public String hello2(@Valid Person person,//实体类前面加@Valid,异常信息存在BindingResult result中
BindingResult result) {
List<String> list = new ArrayList<>();
if (result.hasErrors()) {
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError allError : allErrors) {
list.add(allError.getDefaultMessage());
}
}
return list.toString();
}
测试
参考
Spring Boot之Validation自定义实现总结_木小鱼的笔记-CSDN博客_validation 自定义
遇到的问题
1)javax.validation.UnexpectedTypeException
字符串非空用@NotEmpty,数字非空用@NotNull二者是不一样的
如果@NotEmpty用在类型是Integer的属性上就会报错