代码简洁之道 beanvalidation 与 hibernate-validator
序言
beanvalidation官网:https://beanvalidation.org/ api的接口
Hibernate-validator官网:http://hibernate.org/validator/ api的实现
一、传统的参数校验
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class UserInfo {
private Long id;
private String name;
private Integer age;
private String email;
private String phone;
private LocalDateTime birthday;
private String personalPage;
}
public class TraditionalTest {
@Test
public void test01(){
UserInfo userInfo = new UserInfo();
validateUserInfo(userInfo);
}
private static void validateUserInfo(UserInfo userInfo){
String name = userInfo.getName();
if (name == null || "".equals(name) || "".equals(name.trim())) {
throw new RuntimeException("name 不符合校验规则");
}
Integer age = userInfo.getAge();
boolean ageValidate = age > 1 && age < 800;
if (!ageValidate) {
throw new RuntimeException("age不符合校验规则,应在(1-800)");
}
}
}
二、javaEE规范的故事
- 是什么?
- 不相关的很多java package组成了javaee规范
- 在哪里?
- javax开头的包
- javax.sql ---- mysql ,sqlserver,oracle …
- Javax.jms ---- activemq
- Javax.servlet ---- tomcat,jetty …
- Javax.persistence ---- hibernate
- Javax.transaction----分布式事务
- javax.xml----jaxp: java api for xml processing
? jdk自带了一些常用的javaee规范,对于没有自带的如果想要使用就需要自己引用了,比如beanvalidation
-
如何制定? jcp官网:https://jcp.org/en/home/index Jsr:JavaSpecification Requests java规范提案, 如beanvalidation的提案有如下3个。
- 由谁:jcp里的成员:https://jcp.org/en/participation/members
提案号 | beanvalidation版本 |
---|
jsr303 | beanvalidation1.0 | jsr349 | beanvalidation1.1 | Jsr380 | beanvalidation2.0 |
-
javax走向jakarta 参考:https://blogs.oracle.com/theaquarium/opening-up-java-ee oracle把javaee规范捐献给eclipse基金会 -
不要和Apache的jakarta混为一谈 2011退休了:https://jakarta.apache.org/
三、非web环境下使用校验
3.1 搭建环境
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>10.0.22</version>
</dependency>
3.2 validator初体验
package com.zs.validation;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class ValidationUtil {
private static Validator validator;
static {
validator = Validation.buildDefaultValidatorFactory().getValidator();
}
public static List<String> valid(Object obj) {
Set<ConstraintViolation<Object>> set = validator.validate(obj);
List<String> list = set.stream().map(v -> "属性:" + v.getPropertyPath() + ",属性的值" +
v.getInvalidValue() + ",校验不通过的提示信息:" + v.getMessage())
.collect(Collectors.toList());
return list;
}
}
添加注解
import jakarta.validation.constraints.NotNull;
@Data
public class UserInfo {
@NotNull
private String name;
测试
@Test
public void test01(){
UserInfo userInfo = new UserInfo();
userInfo.setAge(2);
List<String> list = ValidationUtil.valid(userInfo);
System.out.println(list);
}
[属性:name,属性的值null,校验不通过的提示信息:不能为null]
3.3 validato加载原理
spi机制
3.4 常用的校验约束注解
- Bean Validation中内置的 constraint
@Null 被注释的元素必须为null
@NotNull 被注释的元素必须不为null
@NotEmpty 被注释的集合(size > 0)/字符串(!=null && !"")
@NotBlank !=null && !"" && !" "
@AssertTrue 被注释的元素必须为true
@AssertFalse 被注释的元素必须为false
@Min(value) 被注释的元素必须是一个数字,>=
@Max(value) 被注释的元素必须是一个数字,<=
@DecimalMin(value) >=
@DecimalMax(value) <=
@Size(max,min) 被注释的元素的大小必须在指定的范围内
@Digits(integer,fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@PastOrPresent 时间
@NegativeOrZero <=0
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
@Email 被注释的元素必须是电子邮箱地址
- Hibernate Validator附加的 constraint: org.hibernate.validator.constraints
@Length 被注释的字符串的大小必须在指定的范围内
@Range 被注释的元素必须在适合的范围内
@URL 一个url
@NotBlank
private String name;
@Range(min=1,max=800)
private Integer age;
@NotBlank
@Email
private String email;
@Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$")
private String phone;
@NotNull
@Past
private LocalDateTime birthday;
@URL
private String personalPage;
package com.zs.validation.bean;
import jakarta.validation.constraints.*;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.constraints.URL;
import java.time.LocalDateTime;
@Data
public class UserInfo {
private Long id;
@NotBlank
private String name;
@Range(min=1,max=800)
private Integer age;
@NotBlank
@Email
private String email;
@Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$")
private String phone;
@NotNull
@Past
private LocalDateTime birthday;
@URL
private String personalPage;
}
测试
package com.zs.validation;
import com.zs.validation.bean.UserInfo;
import org.junit.Test;
import java.time.LocalDateTime;
import java.util.List;
public class TraditionalTest {
@Test
public void test01(){
UserInfo userInfo = new UserInfo();
userInfo.setAge(1);
userInfo.setName("zs");
userInfo.setEmail("aaaa@qq.com");
userInfo.setPhone("13516466501");
userInfo.setBirthday(LocalDateTime.now().minusDays(1));
userInfo.setPersonalPage("http://www.baidu.com");
List<String> list = ValidationUtil.valid(userInfo);
System.out.println(list);
}
private static void validateUserInfo(UserInfo userInfo){
String name = userInfo.getName();
if (name == null || "".equals(name) || "".equals(name.trim())) {
throw new RuntimeException("name 不符合校验规则");
}
Integer age = userInfo.getAge();
boolean ageValidate = age > 1 && age < 800;
if (!ageValidate) {
throw new RuntimeException("age不符合校验规则,应在(1-800)");
}
}
}
3.5 约束和校验类的绑定原理
@NotNull
NotNullValidator 类校验 NotNull注解
同理 @Xxx注解的校验器类为XxxValidator
org.hibernate.validator.internal.metadata.core.ConstraintHelper
if (enabledBuiltinConstraints.contains(BuiltinConstraint.JAKARTA_VALIDATION_CONSTRAINTS_NOT_BLANK)) {
putBuiltinConstraint(tmpConstraints, NotBlank.class, NotBlankValidator.class);
}
private boolean isBuiltinConstraint(Class<? extends Annotation> annotationType) {
return BuiltinConstraint.isBuiltin(annotationType.getName());
}
注意:一个注解约束可能对应多个约束Validator,如@NotEmpty
3.6 自定义校验信息
@NotBlank(message = "你的名字不能为空")
private String name;
@Min(value = 18,message = "你的名字小于{value},禁止进入")
private Integer age;
public static List<String> valid(Object obj) {
Set<ConstraintViolation<Object>> set = validator.validate(obj);
List<String> list = set.stream().map(v ->
"属性:" + v.getPropertyPath() +
",属性的值" + v.getInvalidValue() +
",校验不通过的提示信息:" + v.getMessage() +
",消息模板(为被替换的提示信息):" + v.getMessageTemplate()
)
.collect(Collectors.toList());
return list;
}
3.7 分组校验
@Data
public class UserInfo {
public interface Add { }
public interface Update { }
@Null(groups = {Add.class, Default.class})
@NotNull(groups = Update.class)
private Long id;
@NotBlank(message = "你的名字不能为空")
private String name;
package com.zs.validation;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class ValidationUtil {
private static Validator validator;
static {
validator = Validation.buildDefaultValidatorFactory().getValidator();
}
public static List<String> valid(Object obj,Class<?>... groups) {
Set<ConstraintViolation<Object>> set = validator.validate(obj,groups);
List<String> list = set.stream().map(v ->
"属性:" + v.getPropertyPath() +
",属性的值" + v.getInvalidValue() +
",校验不通过的提示信息:" + v.getMessage() +
",消息模板(为被替换的提示信息):" + v.getMessageTemplate()
)
.collect(Collectors.toList());
return list;
}
}
测试
@Test
public void test01(){
UserInfo userInfo = new UserInfo();
userInfo.setAge(1);
userInfo.setName("zs");
userInfo.setEmail("aaaa@qq.com");
userInfo.setPhone("13516466501");
userInfo.setBirthday(LocalDateTime.now().minusDays(1));
userInfo.setPersonalPage("http://www.baidu.com");
List<String> list = ValidationUtil.valid(userInfo, UserInfo.Add.class, Default.class);
System.out.println(list);
}
3.8 @Valid级联校验
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class Grade {
@NotBlank
private String no;
}
@NotNull
@Valid
private Grade grade;
}
userInfo.setGrade(new Grade());
List<String> list = ValidationUtil.valid(userInfo, UserInfo.Add.class, Default.class);
3.9 自定义校验规则
注解
package com.zs.validation.annotation;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Documented
@Constraint(validatedBy = {UserStatusValidator.class })
@Target({FIELD})
@Retention(RUNTIME)
public @interface UserStatus {
String message() default "{userStatus必须是范围内的值}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
注解校验器
public class UserStatusValidator implements ConstraintValidator<UserStatus, String> {
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if (s == null) {
return true;
} else {
Set<String> set = new HashSet<>();
set.add("10");
set.add("20");
set.add("30");
return set.contains(s);
}
}
@Override
public void initialize(UserStatus constraintAnnotation) {
}
}
使用
@UserStatus
private String status;
测试
@Test
public void test01(){
UserInfo userInfo = new UserInfo();
userInfo.setAge(19);
userInfo.setName("zs");
userInfo.setEmail("aaaa@qq.com");
userInfo.setPhone("13516466501");
userInfo.setBirthday(LocalDateTime.now().minusDays(1));
userInfo.setPersonalPage("http://www.baidu.com");
userInfo.setGrade(new Grade().setNo("11"));
userInfo.setStatus("10");
List<String> list = ValidationUtil.valid(userInfo, UserInfo.Add.class, Default.class);
System.out.println(list);
}
3.10 快速校验failfast
package com.zs.validation;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import org.hibernate.validator.HibernateValidator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class ValidationUtil {
private static Validator validator;
private static Validator failFastValidator;
static {
validator = Validation.buildDefaultValidatorFactory().getValidator();
failFastValidator = Validation.byProvider(HibernateValidator.class)
.configure().failFast(true)
.buildValidatorFactory().getValidator();
}
public static List<String> valid(Object obj,Class<?>... groups) {
Set<ConstraintViolation<Object>> set = validator.validate(obj,groups);
List<String> list = set.stream().map(v ->
"属性:" + v.getPropertyPath() +
",属性的值" + v.getInvalidValue() +
",校验不通过的提示信息:" + v.getMessage() +
",消息模板(为被替换的提示信息):" + v.getMessageTemplate()
)
.collect(Collectors.toList());
return list;
}
public static List<String> validFailFast(Object obj,Class<?>... groups) {
Set<ConstraintViolation<Object>> set = failFastValidator.validate(obj,groups);
List<String> list = set.stream().map(v ->
"属性:" + v.getPropertyPath() +
",属性的值" + v.getInvalidValue() +
",校验不通过的提示信息:" + v.getMessage() +
",消息模板(为被替换的提示信息):" + v.getMessageTemplate()
)
.collect(Collectors.toList());
return list;
}
}
3.10 非bean入参校验
package com.zs.validation;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.executable.ExecutableValidator;
import org.hibernate.validator.HibernateValidator;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class ValidationUtil {
private static Validator validator;
private static Validator failFastValidator;
private static ExecutableValidator executableValidator;
static {
validator = Validation.buildDefaultValidatorFactory().getValidator();
failFastValidator = Validation.byProvider(HibernateValidator.class)
.configure().failFast(true)
.buildValidatorFactory().getValidator();
executableValidator = validator.forExecutables();
}
public static List<String> valid(Object obj,Class<?>... groups) {
Set<ConstraintViolation<Object>> set = validator.validate(obj,groups);
List<String> list = set.stream().map(v ->
"属性:" + v.getPropertyPath() +
",属性的值" + v.getInvalidValue() +
",校验不通过的提示信息:" + v.getMessage() +
",消息模板(为被替换的提示信息):" + v.getMessageTemplate()
)
.collect(Collectors.toList());
return list;
}
public static List<String> validFailFast(Object obj,Class<?>... groups) {
Set<ConstraintViolation<Object>> set = failFastValidator.validate(obj,groups);
List<String> list = set.stream().map(v ->
"属性:" + v.getPropertyPath() +
",属性的值" + v.getInvalidValue() +
",校验不通过的提示信息:" + v.getMessage() +
",消息模板(为被替换的提示信息):" + v.getMessageTemplate()
)
.collect(Collectors.toList());
return list;
}
public static <T> List<String> validNotBean(T object, Method method, Object[] parameterValues, Class<?>... groups) {
Set<ConstraintViolation<Object>> set = executableValidator.validateParameters(object,method,parameterValues,groups);
List<String> list = set.stream().map(v ->
"属性:" + v.getPropertyPath() +
",属性的值" + v.getInvalidValue() +
",校验不通过的提示信息:" + v.getMessage() +
",消息模板(为被替换的提示信息):" + v.getMessageTemplate()
)
.collect(Collectors.toList());
return list;
}
}
public String getByName(@NotNull String name) {
StackTraceElement st = Thread.currentThread().getStackTrace()[1];
String methodName = st.getMethodName();
Method method = null;
try {
method = this.getClass().getDeclaredMethod(methodName,String.class);
} catch (Exception e) {
e.printStackTrace();
}
List<String> strings = ValidationUtil.validNotBean(this, method, new Object[]{name});
System.out.println(strings);
return "ok";
}
@Test
public void test02(){
UserInfoService userInfoService = new UserInfoService();
String byName = userInfoService.getByName(null);
System.out.println(byName);
}
四、web环境中使用
4.1 搭建springboot环境
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.0</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserInfoHandler {
@GetMapping("/getByName")
public String getByName(String name){
return name + "ok";
}
}
package com.zs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
}
4.2 使用@Valid自动校验
@GetMapping("/addUser")
public String addUser(UserInfo userInfo){
List<String> result = ValidationUtil.valid(userInfo);
if (result.size() > 0) {
return "failed";
} else {
return "success";
}
}
@GetMapping("/addUser2")
public String addUser2(@Valid UserInfo userInfo, BindingResult bindingResult){
if (bindingResult.hasErrors()) {
List<ObjectError> allErrors = bindingResult.getAllErrors();
for (ObjectError error : allErrors) {
System.out.println(error.getObjectName() + "::" + error.getDefaultMessage());
}
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage()
+ ",当前没通过校验规则的值是:" + fieldError.getRejectedValue());
}
}
return "ok";
}
userInfo::你的名字不能为空 userInfo::不能为null userInfo::不能为空 userInfo::不能为null name:你的名字不能为空,当前没通过校验规则的值是:null birthday:不能为null,当前没通过校验规则的值是:null email:不能为空,当前没通过校验规则的值是:null grade:不能为null,当前没通过校验规则的值是:null
4.3 使用@Validated自动校验 (指定分组)
@GetMapping("/addUser3")
public String addUser3(@Validated(value={UserInfo.Add.class, Default.class}) UserInfo userInfo, BindingResult bindingResult){
if (bindingResult.hasErrors()) {
List<ObjectError> allErrors = bindingResult.getAllErrors();
for (ObjectError error : allErrors) {
System.out.println(error.getObjectName() + "::" + error.getDefaultMessage());
}
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage()
+ ",当前没通过校验规则的值是:" + fieldError.getRejectedValue());
}
}
return "ok";
}
4.4 统一异常处理
@GetMapping("/addUser4")
public String addUser4(@Validated(value={UserInfo.Add.class, Default.class}) UserInfo userInfo){
return "ok";
}
@ExceptionHandler(BindException.class)
public String handleEx(BindException e) {
List<FieldError> fieldErrors = e.getFieldErrors();
StringBuilder stringBuilder = new StringBuilder();
for (FieldError fe : fieldErrors) {
stringBuilder.append("属性:").append(fe.getField())
.append("校验不通过,原因:").append(fe.getDefaultMessage())
.append(";");
}
return stringBuilder.toString();
}
4.5 区别@Validated 和 @Valid
-
@Validated 可以指定分组 -
@Validated 支持方法参数的自动校验
@RestController
@Validated
public class UserInfoHandler {
@GetMapping("/getByName")
public String getByName(@NotNull String name){
return name + "ok";
}
@ExceptionHandler(BindException.class)
@ResponseBody
public String handleEx(BindException e) {
List<FieldError> fieldErrors = e.getFieldErrors();
StringBuilder stringBuilder = new StringBuilder();
for (FieldError fe : fieldErrors) {
stringBuilder.append("属性:").append(fe.getField())
.append("校验不通过,原因:").append(fe.getDefaultMessage())
.append(";");
}
return stringBuilder.toString();
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public List<String> handleEx(ConstraintViolationException e) {
Set<ConstraintViolation<?>> set = e.getConstraintViolations();
List<String> list = set.stream().map(v ->
"属性:" + v.getPropertyPath() +
",属性的值" + v.getInvalidValue() +
",校验不通过的提示信息:" + v.getMessage() +
",消息模板(为被替换的提示信息):" + v.getMessageTemplate()
)
.collect(Collectors.toList());
return list;
}
示例一
一、背景
在某些项目场景中,需要使用代码校验实体类的参数值是否符合需求,并且返回值是动态的情况下,此时需要校验工具类来实现此功能。
二、hibernate-validator
1.maven
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.16.Final</version>
</dependency>
2.校验工具类
package com.asyf.demo.other_api.hibernatevalidator;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.HibernateValidator;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.groups.Default;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Slf4j
public class ValidateUtil {
private static Validator validator;
static {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(false)
.buildValidatorFactory();
validator = validatorFactory.getValidator();
}
public static <T> ValidationResult validateEntity(T obj) {
Set<ConstraintViolation<T>> validateSet = validator.validate(obj, Default.class);
return buildValidationResult(validateSet);
}
public static <T> ValidationResult validateProperty(T obj, String propertyName) {
Set<ConstraintViolation<T>> validateSet = validator.validateProperty(obj, propertyName, Default.class);
return buildValidationResult(validateSet);
}
private static <T> ValidationResult buildValidationResult(Set<ConstraintViolation<T>> validateSet) {
ValidationResult validationResult = new ValidationResult();
if (!validateSet.isEmpty()) {
validationResult.setHasErrors(true);
Map<String, String> errorMsgMap = new HashMap<>();
for (ConstraintViolation<T> constraintViolation : validateSet) {
errorMsgMap.put(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage());
}
validationResult.setErrorMsg(errorMsgMap);
}
return validationResult;
}
public static void main(String[] args) {
User user = new User();
ValidationResult validationResult = ValidateUtil.validateEntity(user);
log.info(JSONUtil.toJsonStr(validationResult));
}
}
package com.asyf.demo.other_api.hibernatevalidator;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import java.text.MessageFormat;
import java.util.Map;
@Data
public class ValidationResult {
private boolean hasErrors;
private Map<String, String> errorMsg;
public String getMessage() {
if (errorMsg == null || errorMsg.isEmpty()) {
return StringUtils.EMPTY;
}
StringBuilder message = new StringBuilder();
errorMsg.forEach((key, value) -> {
message.append(MessageFormat.format("{0}:{1} \r\n", key, value));
});
return message.toString();
}
}
3.自定义校验注解
package com.asyf.demo.other_api.hibernatevalidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyValidatorAnnotation {
String message() default "性别有误";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String type() default "abc";
}
package com.asyf.demo.other_api.hibernatevalidator;
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
@Slf4j
public class MyConstraintValidator implements ConstraintValidator<MyValidatorAnnotation, String> {
private MyValidatorAnnotation annotation;
public MyConstraintValidator() {
}
@Override
public void initialize(MyValidatorAnnotation annotation) {
this.annotation = annotation;
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
log.info("校验 type:{}", annotation.type());
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("重新添加错误提示语句").addConstraintViolation();
return "正确的值".equals(value);
}
}
4.校验实体类
package com.asyf.demo.other_api.hibernatevalidator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class User {
@MyValidatorAnnotation(type = "1", message = "name错误")
private String name;
@NotNull
@JsonIgnore
private Integer age;
@MyValidatorAnnotation(type = "2", message = "email错误")
private String email;
}
5.main函数测试
public static void main(String[] args) {
User user = new User();
ValidationResult validationResult = ValidateUtil.validateEntity(user);
log.info(JSONUtil.toJsonStr(validationResult));
}
三、测试结果
INFO [main] - 校验 type:2
INFO [main] - 校验 type:1
INFO [main] - {"hasErrors":true,"errorMsg":{"name":"重新添加错误提示语句","email":"重新添
https://www.bilibili.com/video/BV1UE411t7BZ?spm_id_from=333.337.search-card.all.click&vd_source=746baba3d7924e4ac64a8318afa1567f
|