当前位置: 首页 > news >正文

spring数据校验

数据校验

概述

在开发中,会存在参数校验的情况,如:注册时,校验用户名不能为空、用户名长度不超过20个字符,手机号格式合法等。如果使用普通方式,会将校验代码和处理逻辑耦合在一起,在需要新增一种校验时,也需要修改很多地方。

spring validation允许通过注解的方式来定义校验规则,把校验和业务分离开。它其实就是对Hibernate Validation进一步的封装。

spring中的校验方式

  • 通过实现org.springframework.validation.Validator接口,然后在代码中调用这个类。
  • 按照Bean Validation方式进行校验(通过注解方式)。
  • 基于方法实现校验。

通过Validator接口实现校验

实现步骤

1、依赖引入
<dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>8.0.1.Final</version>
</dependency><dependency><groupId>org.glassfish</groupId><artifactId>jakarta.el</artifactId><version>5.0.0-M1</version>
</dependency>
2、创建实体类
public class Person {private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}
}
3、编写校验类
public class PersonValidator implements Validator {/*** 此方法用来表示此校验用在哪个类型上* @param clazz* @return*/@Overridepublic boolean supports(Class<?> clazz) {return Person.class.equals(clazz);}/*** 此方法是设置校验逻辑的地点,其中ValidatorUtils,是Spring封装的工具类。帮助快速实现校验* @param target* @param errors*///校验规则@Overridepublic void validate(Object target, Errors errors) {//name不能为空ValidationUtils.rejectIfEmpty(errors, "name", "name Empty", "name is null");//age不能小于0,不能大于200Person p = (Person)target;if (p.getAge() <= 0){errors.rejectValue("age", "age.value.error", "age<0");} else if (p.getAge() >= 200) {errors.rejectValue("age", "age.value.error.max", "age>200");}}
}
4、测试
@Test
public void testValidation(){//创建Person对象Person person = new Person();person.setAge(30);person.setName(null);//创建person对应对象DataBinder binder = new DataBinder(person);//设置校验器binder.setValidator(new PersonValidator());//调用方法、执行校验binder.validate();//输出校验结果BindingResult result = binder.getBindingResult();System.out.println("result.getAllErrors() = " + result.getAllErrors());
}
/*
* Empty.name,name Empty.java.lang.String,name Empty]; arguments []; default message [name is null]]
* */

Bean Validation注解实现

使用Bean Validation校验方式,需要使用到javax.validation.ValidatorFactoryjavax.validation.Validator注入到容器中,spring默认有一个实现类LocalValidatorFacoryBean,它实现了上面Bean Validation中的接口,并且也实现了org.springframeworkvalidation.Validator接口。

实现步骤

1、创建配置类,配置LocalValidatorFactoryBean
@Configuration
@ComponentScan("com.louis.testvalidationtwo")
public class ValidationConfig {@Beanpublic LocalValidatorFactoryBean validator(){return new LocalValidatorFactoryBean();}
}
2、创建实体类

定义属性,生成get、set方法,在属性上面使用注解设置校验规则。

public class User {@NotNullprivate String name;@Min(0)@Max(200)private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
3、创建校验器

①使用原生的校验器

@Service
public class MyValidationOne {//使用原生的校验器@Autowiredprivate Validator validator;public boolean testValidator(User user){Set<ConstraintViolation<User>> validate = validator.validate(user);return validate.isEmpty();}

②使用spring中的validation

@Service
public class MyValidationTwo {//使用spring中的validation@Autowiredprivate Validator validator;public List testValidatorTwo(User user){BindException bindException = new BindException(user, user.getName());validator.validate(user, bindException);List<ObjectError> allErrors = bindException.getAllErrors();return allErrors;}
}
4、测试

使用方式①

@Test
public void testValidator(){ApplicationContext context = new AnnotationConfigApplicationContext(ValidationConfig.class);MyValidationOne validationOne = context.getBean(MyValidationOne.class);User user = new User();boolean result = validationOne.testValidator(user);System.out.println("result = " + result);/*result = false*/
}

使用方式②

@Test
public void testValidatorTwo(){ApplicationContext context = new AnnotationConfigApplicationContext(ValidationConfig.class);MyValidationTwo validationTwo = context.getBean(MyValidationTwo.class);User user = new User();List result = validationTwo.testValidatorTwo(user);System.out.println("result = " + result);/*Object name must not be null*/
}

常用注解

注解说明
@NotNull限制必须不为空
@NotEmpty只作用于字符串类型,字符串不为空,且长度不为0
@NotBlank 只作用于字符串类型,字符串不为空且trim()后也并不为空
@DecimalMax(value)限制必须为一个不大于指定值的数字,小数存在精度
@DecimalMin(value)限制必须为一个不小于指定值的数字,小数存在精度
@Max(value)限制必须为一个不大于指定值的数字
@Min(value)限制必须为一个不小于指定值的数字
@Pattern(value)限制必须符合指定的正则表达式
@Size(max, min)限制字符串长度必须在min到max之间
@Email验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

基于方法实现校验

实现步骤

1、创建配置类
@Configuration
@ComponentScan("com.louis.validationbymethod")
public class ValidationConfig {@Beanpublic MethodValidationPostProcessor validationPostProcessor(){return new MethodValidationPostProcessor();}
}
2、创建实体类

使用注解设置校验规则

public class User {@NotNullprivate String name;@Max(200)@Min(0)private int age;@NotBlank(message = "手机号不能为空")@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$", message = "手机号格式错误")private String phone;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}
}
3、编写校验器
@Service
@Validated
public class MyService {public String testMethod(@NotNull @Valid User user){return user.toString();}
}
4、测试
@Test
public void testValidationByMethod(){ApplicationContext context = new AnnotationConfigApplicationContext(ValidationConfig.class);MyService service = context.getBean(MyService.class);service.testMethod(new User());/*testMethod.arg0.phone: 手机号不能为空, testMethod.arg0.name: 不能为null*/
}

实现自定义校验

实现步骤

1、自定义校验注解

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {CannotHaveBlankValidator.class})//表示指定校验器的类,实现真正的校验器规则
public @interface CannotHaveBlank {//默认的出现错误的提示信息String message() default "不能包含空格";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface List {CannotHaveBlank[] value();}
}

2、编写校验规则

public class CannotHaveBlankValidator implements ConstraintValidator<CannotHaveBlank, String> {@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {if(value != null &&value.contains(" ")){//获取默认提示信息String defaultConstraintMessageTemplate = context.getDefaultConstraintMessageTemplate();System.out.println("default message:"+defaultConstraintMessageTemplate);//禁用默认提示信息context.disableDefaultConstraintViolation();//设置提示语context.buildConstraintViolationWithTemplate("can not constrains blank").addConstraintViolation();return false;}return false;}
}

3、创建实体类

public class User {@NotNullprivate String name;@Max(200)@Min(0)private int age;@NotBlank(message = "手机号不能为空")@Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$", message = "手机号格式错误")private String phone;@CannotHaveBlankprivate String message;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}

4、测试

//使用基于方法实现校验的校验器
public class TestValidationByMethod {@Testpublic void testValidationByMethod(){ApplicationContext context = new AnnotationConfigApplicationContext(ValidationConfig.class);MyService service = context.getBean(MyService.class);User user = new User();user.setAge(30);user.setName("Louie");user.setPhone("18111111111");user.setMessage("L o u i s");service.testMethod(user);
/*default message:不能包含空格
jakarta.validation.ConstraintViolationException: testMethod.arg0.message: can not constrains blank*/}
}
http://www.lryc.cn/news/95702.html

相关文章:

  • 因材施教,有道发布“子曰”教育大模型,落地虚拟人口语教练等六大应用
  • golang waitgroup
  • 单列模式多学两遍
  • Spring Cloud【SkyWalking网络钩子Webhooks、SkyWalking钉钉告警、SkyWalking邮件告警】(十六)
  • 【力扣每日一题】2023.7.25 将数组和减半的最少操作次数
  • Docker-Compose 轻松搭建 Grafana+InfluxDb 实用 Jmeter 监控面板
  • 异构线程池的c++实现方案
  • Python实现抽象工厂模式
  • @vue/cli安装
  • 用友全版本任意文件上传漏洞复现
  • 程序员面试系列,MySQL常见面试题?
  • 前端Web实战:从零打造一个类Visio的流程图拓扑图绘图工具
  • 2023牛客暑期多校第二场部分题解
  • 20230724将真我Realme手机GT NEO3连接到WIN10的电脑的步骤
  • 黑马 pink h5+css3+移动端前端
  • Docker的七项优秀实践
  • 【数据结构】24王道考研笔记——图
  • zabbix钉钉报警
  • Spring 源码解读
  • 练习时长两年半的网络安全防御“first”
  • HttpRunner自动化测试之响应中文乱码处理
  • idea使用命令将jar包导入到maven仓库中
  • zookeeper学习(一) Standalone模式(单机模式)安装
  • native webrtc支持切换音频采集设备和获取裸流
  • HR怎么看待PMP证书呢?
  • API接口:如何通过使用手机归属地查询
  • 小创业公司死亡剧本
  • 国产化的接口测试、接口自动化测试工具Apipost的介绍及使用
  • 【MySQL】不允许你不知道如何插入数据
  • Vue 渲染流程详解