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.ValidatorFactory
和javax.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*/}
}
相关文章:
spring数据校验
数据校验 概述 在开发中,会存在参数校验的情况,如:注册时,校验用户名不能为空、用户名长度不超过20个字符,手机号格式合法等。如果使用普通方式,会将校验代码和处理逻辑耦合在一起,在需要新增一…...

因材施教,有道发布“子曰”教育大模型,落地虚拟人口语教练等六大应用
因材施教的教育宗旨下,大模型浪潮中,网易有道凭借其对教育场景的深入理解和对商业化的理性思考,为行业树立了垂直大模型的典范。 7月26日,教育科技公司网易有道举办了“powered by 子曰”教育大模型应用成果发布会。会上重磅推出了…...

golang waitgroup
案例 WaitGroup 可以解决一个 goroutine 等待多个 goroutine 同时结束的场景,这个比较常见的场景就是例如 后端 worker 启动了多个消费者干活,还有爬虫并发爬取数据,多线程下载等等。 我们这里模拟一个 worker 的例子 package mainimport (…...
单列模式多学两遍
单例模式 单例模式(Singleton Pattern,也称为单件模式),使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。 定义单例类 ● 私有化它的构造函数,…...

Spring Cloud【SkyWalking网络钩子Webhooks、SkyWalking钉钉告警、SkyWalking邮件告警】(十六)
目录 分布式请求链路追踪_SkyWalking网络钩子Webhooks 分布式请求链路追踪_SkyWalking钉钉告警 分布式请求链路追踪_SkyWalking邮件告警 分布式请求链路追踪_SkyWalking网络钩子Webhooks Wbhooks网络钩子 Webhok可以简单理解为是一种Web层面的回调机制。告警就是一个事件&a…...

【力扣每日一题】2023.7.25 将数组和减半的最少操作次数
目录 题目: 示例: 分析: 代码运行结果: 题目: 示例: 分析: 题目给我们一个数组,我们每次可以将任意一个元素减半,问我们操作几次之后才可以将整个数组的和减半&…...

Docker-Compose 轻松搭建 Grafana+InfluxDb 实用 Jmeter 监控面板
目录 前言: 1、背景 2、GranfanaInfluxDB 配置 2.1 服务搭建 2.2 配置 Grafana 数据源 2.3 配置 Grafana 面板 3、Jmeter 配置 3.1 配置 InfluxDB 监听器 3.2 实际效果 前言: Grafana 和 InfluxDB 是两个非常流行的监控工具,它们可…...

异构线程池的c++实现方案
概要 通常线程池是同质的,每个线程都可以执行任意的task(每个线程中的task顺序执行),如下图所示: 但本文所介绍的线程和task之间有绑定关系,如A task只能跑在A thread上(因此称为异构线程池&am…...

Python实现抽象工厂模式
抽象工厂模式是一种创建型设计模式,用于创建一系列相关或依赖对象的家族,而无需指定具体类。在Python中,可以通过类和接口的组合来实现抽象工厂模式。 下面是一个简单的Python实现抽象工厂模式的示例: # 抽象产品接口 class Abs…...

@vue/cli安装
vue/cli安装 1、全局安装vue/cli包2、查看是否成功 1、全局安装vue/cli包 yarn global add vue/cli2、查看是否成功 vue -V...

用友全版本任意文件上传漏洞复现
声明 本文仅用于技术交流,请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。 文章作者拥有对此文章的修改和解释权。如欲转载或传播此文章,…...
程序员面试系列,MySQL常见面试题?
原文链接 一、索引相关的面试题 (1)索引失效的情况有哪些 在MySQL查询时,以下情况可能会导致索引失效,无法使用索引进行高效的查询: 数据类型不匹配:如果查询条件中的数据类型与索引列的数据类型不匹配&…...

前端Web实战:从零打造一个类Visio的流程图拓扑图绘图工具
前言 大家好,本系列从Web前端实战的角度,给大家分享介绍如何从零打造一个自己专属的绘图工具,实现流程图、拓扑图、脑图等类Visio的绘图工具。 你将收获 免费好用、专属自己的绘图工具前端项目实战学习如何从0搭建一个前端项目等基础框架项…...
2023牛客暑期多校第二场部分题解
索引 ABCDEFGHIK A 队友开的题,说是其实就是问能不能用若干个数异或出来某个数。 应该就是线性基板子,然后他写了一下就过了。 B 一开始看没什么人过不是很敢开,结果到后面一看题——这不是最大权闭合子图板子吗??…...

20230724将真我Realme手机GT NEO3连接到WIN10的电脑的步骤
20230724将真我Realme手机GT NEO3连接到WIN10的电脑的步骤 2023/7/24 23:23 缘起:因为找使用IMX766的手机,找到Realme手机GT NEO3了。 同样使用IMX766的还有:Redmi Note12Pro 5G IMX766 旗舰影像 OIS光学防抖 OLED柔性直屏 8GB256GB时光蓝 现…...

黑马 pink h5+css3+移动端前端
网页概念 网页是网站的一页,网页有很多元素组成,包括视频图片文字视频链接等等,以.htm和.html后缀结尾,俗称html文件 HTML 超文本标记语言,描述网页语言,不是编程语言,是标记语言,有标签组成 超文本指的是不光文本,还有图片视频等等标签 常用浏览器 firefox google safari…...
Docker的七项优秀实践
众所周知,作为一个文本文档,Dockerfile包含了用户创建镜像的所有命令和说明。Docker可以通过读取Dockerfile中指令的方式,去自动构建镜像。因此,大家往往认为编写Dockerfile理应非常简单,只需从互联网上选择一个示例&a…...

【数据结构】24王道考研笔记——图
六、图 目录 六、图定义及基本术语图的定义有向图以及无向图简单图以及多重图度顶点-顶点间关系连通图、强连通图子图连通分量强连通分量生成树生成森林边的权、带权网/图特殊形态的图 图的存储及基本操作邻接矩阵邻接表法十字链表邻接多重表分析对比图的基本操作 图的遍历广度…...

zabbix钉钉报警
登录钉钉客户端,创建一个群,把需要收到报警信息的人员都拉到这个群内. 然后点击群右上角 的"群机器人"->"添加机器人"->"自定义", 记录该机器人的webhook值。 添加机器人 在钉钉群中,找到只能群助手 添加机器人 选择自定义机…...

Spring 源码解读
1、Spring 的结构组成 1.1、核心类介绍 Spring 中有两个最核心的类 1 DefaultListableBeanFactory XmlBeanFactory 继承自 DefaultListableBeanFactory,而DefaultListableBeanFactory 是整个 bean加载的核心部分,是 Spring 注册及加载 bean 的默认实现…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...