Spring Boot 如何使用 @Validated 注解进行数据校验

news2024/9/20 18:32:13

Spring Boot 如何使用 @Validated 注解进行数据校验

在开发应用程序时,数据校验通常是不可避免的。Spring Boot 提供了许多选项来验证应用程序中的数据,其中一个选项是使用 @Validated 注解。本文将介绍如何使用 @Validated 注解进行数据校验,并提供一些示例代码来帮助您更好地理解。

在这里插入图片描述

@Validated 简介

@Validated 是 Spring Boot 中的一个注解,用于验证方法参数、请求参数和请求体。它是 javax.validation 中的 @Valid 注解的扩展,但提供了更多的功能,例如分组校验和参数校验顺序。

在使用 @Validated 注解时,需要在 Spring Boot 应用程序中添加 spring-boot-starter-validation 依赖,以便使用校验器。校验器是 javax.validation 包中的一个实现,用于验证对象和属性。

在方法参数上使用 @Validated

在使用 @Validated 注解时,可以将其放置在方法参数上,以验证方法参数的有效性。

@PostMapping("/users")
public User createUser(@RequestBody @Validated User user) {
    // 处理用户创建逻辑
}

在上面的代码中,@Validated 注解用于验证 @RequestBody 注解中传递的 User 对象是否有效。如果 User 对象无效,将会抛出 MethodArgumentNotValidException 异常。如果您需要自定义异常处理程序来处理此异常,可以使用 @ExceptionHandler 注解。

您还可以使用 BindingResult 对象来获取验证结果:

@PostMapping("/users")
public User createUser(@RequestBody @Validated User user, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        // 处理验证错误
    }
    // 处理用户创建逻辑
}

在上面的代码中,如果有任何验证错误,BindingResult 对象将包含这些错误。您可以使用 hasErrors() 方法来检查是否有错误,并使用 getFieldErrors()getGlobalErrors() 方法来获取错误列表。

在请求参数上使用 @Validated

您可以使用 @Validated 注解来验证请求参数。在此示例中,我们将使用 @RequestParam 注解来获取请求参数:

@GetMapping("/users")
public User getUser(@RequestParam("id") @Min(1) Long id) {
    // 处理获取用户逻辑
}

在上面的代码中,@Validated 注解用于验证 @RequestParam 注解中传递的 id 参数是否有效。如果 id 无效,将会抛出 MethodArgumentNotValidException 异常。

在请求体中使用 @Validated

您可以使用 @Validated 注解来验证请求体中的对象。在此示例中,我们将使用 @RequestBody 注解来获取请求体:

@PostMapping("/users")
public User createUser(@RequestBody @Validated User user) {
    // 处理用户创建逻辑
}

在上面的代码中,@Validated 注解用于验证 @RequestBody 注解中传递的 User 对象是否有效。如果 User 对象无效,将会抛出 MethodArgumentNotValidException 异常。

校验分组

默认情况下,校验器将验证对象上的所有注解。但是,有时您可能希望将验证分成几个组。例如,您可能需要在创建对象时验证所有属性,但在更新对象时只验证必填属性。

要定义分组,请使用 @javax.validation.groups.Default 注解作为默认组,并使用自定义注解来定义其他组。在下面的示例中,我们定义了 CreateUpdate 两个组:

public interface Create {}
public interface Update {}

public class User {
    @NotNull(groups = Create.class)
    private String name;

    @NotNull(groups = {Create.class, Update.class})
    private String email;

    // getters/setters omitted
}

在上面的代码中,@NotNull 标记了 nameemail 属性,但是它们的 groups 属性不同。 name 属性只在 Create 组中验证,而 email 属性在 CreateUpdate 组中验证。

要在使用 @Validated 注解时指定组,请将组作为第二个参数传递给 @Validated 注解。在下面的示例中,我们将 Create 组传递给 @Validated 注解:

@PostMapping("/users")
public User createUser(@RequestBody @Validated(Create.class) User user) {
    // 处理用户创建逻辑
}

在上面的代码中,@Validated 注解仅验证 Create 组中的注解,因此仅验证 name 属性。

定义自定义校验器

有时,内置的校验器无法满足您的需求。例如,您可能需要验证用户名是否唯一,这需要访问数据库。在这种情况下,您可以定义自己的校验器。

要定义自定义校验器,请创建一个实现 javax.validation.ConstraintValidator 接口的类。在下面的示例中,我们将创建一个用于验证用户名是否唯一的校验器:

public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {
    @Autowired
    private UserRepository userRepository;

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        return userRepository.findByUsername(value) == null;
    }
}

在上面的代码中,UniqueUsernameValidator 实现了 ConstraintValidator 接口,该接口有两个泛型参数。第一个参数是自定义注解的类型,第二个参数是要验证的值的类型。

isValid() 方法中,我们验证了 value 是否为 null,如果不是,则检查数据库中是否已存在具有相同用户名的用户。如果不存在,则返回 true,否则返回 false

定义了自定义校验器后,我们需要创建一个自定义注解,以便在代码中使用。在下面的示例中,我们将创建一个 @UniqueUsername 注解:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {UniqueUsernameValidator.class})
public @interface UniqueUsername {
    String message() default "用户名已存在";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

在上面的代码中,我们使用 @Constraint 注解将 UniqueUsernameValidator@UniqueUsername 注解关联起来。我们还定义了默认的错误消息,以及 groupspayload 属性,这些属性可以用于分组和元数据。

现在,我们可以在任何需要验证用户名是否唯一的地方使用 @UniqueUsername 注解:

public class User {
    @NotNull
    @UniqueUsername
    private String username;

    // getters/setters omitted
}

在上面的代码中,我们在 username 属性上使用了 @UniqueUsername 注解,这将调用我们定义的自定义校验器来验证用户名是否唯一。

总结

在本文中,我们介绍了如何使用 @Validated 注解进行数据校验。我们还介绍了如何在方法参数、请求参数和请求体上使用 @Validated 注解,以及如何定义分组和自定义校验器。通过使用 @Validated 注解,您可以轻松地验证应用程序中的数据,并确保数据的完整性和一致性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/674421.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

操作系统-操作系统结构

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

【计算机组成原理】Yy-z02硬布线模型机设计

目录 一、Yy-z02模型机的系统结构 二、Yy-z02模型机的数据通路 三、Yy-z02模型机的指令执行 四、Yy-z02模型机的硬布线控制器 一、Yy-z02模型机的系统结构 指令系统的实现 <--- 构造它的硬件系统 硬件系统构造过程&#xff1a; 分析指令格式和各指令的功能确定部件连…

《机器学习公式推导与代码实现》chapter16-集成学习对比与调参

《机器学习公式推导与代码实现》学习笔记&#xff0c;记录一下自己的学习过程&#xff0c;详细的内容请大家购买作者的书籍查阅。 集成学习&#xff1a;对比与调参 虽然现在深度学习大行其道&#xff0c;但以XGBoost、LightGBM、CatBoost为代表的Boosting算法仍有其广泛的用武…

【Applied Algebra】有限状态机和模型检测初探

【Applied Algebra】有限状态机和模型检测初探 摘要:有限状态机(FSM)和模型检测有密切的联系。有限状态机提供了一种用状态转换图来表示系统行为的简单方法。而模型检测是一种针对形式化模型&#xff08;例如有限状态机&#xff09;的验证技术&#xff0c;旨在自动验证模型是否…

css基础(一)

目录 思维导图 ​一、css简介 1.1 css语法规范 1.2 css代码规格 1. 样式格式书写 2. 样式大小写 3. 空格规范 二、css选择器 2.1 CSS 选择器的作用 2.2 选择器分类 2.3 标签选择器 2.4 类选择器 2.4 类选择器-多类名 2.5 id 选择器 2.6 通配符选择器 2.7 基础选择器总结 三、CS…

D. Running Miles(公式转换)

Problem - D - Codeforces 有一条长为n的街道&#xff0c;其中第i个景点距离街道起点i英里。第i个景点的美丽值为bi。你想要在离街道起点l英里和r英里处开始和结束慢跑。当你跑步时&#xff0c;你会看到你经过的景点&#xff08;包括起点和终点处的景点&#xff09;。你对沿途慢…

Microsoft365有用吗?2023最新版office有哪些新功能?

office自97版到现在已有20多年&#xff0c;一直是作为行业标准&#xff0c;格式和兼容性好&#xff0c;比较正式&#xff0c;适合商务使用。包含多个组件&#xff0c;除了常用的word、excel、ppt外&#xff0c;还有收发邮件的outlook、管理数据库的access、排版桌面的publisher…

CENTOS上的网络安全工具(二十五)SPARK+NetSA Security Tools容器化部署(1)

一、第三代YAF YAF&#xff08;Yet Another Flowmeter&#xff09;是作为CERT NetSA安全工具套件的传感器部分存在的&#xff0c;支持输入实时数据流和PCAP文件&#xff0c;解析并输出流数据&#xff0c;或针对特定协议的深包检测元数据。目前&#xff0c;YAF在整个系统的作用如…

【js30天挑战】第三天:css变量

效果图&#xff1a; 学到的东西 HTML&CSS部分 css变量写法 //定义:root{ //:root 是 CSS 选择器&#xff0c;它匹配文档的根元素&#xff0c;也就是 html 元素。 --base:#FF0081;--spacing:10px;--blur:0px;} //使用img {filter: blur(var(--blur));}input: range类型…

Redis - 数据结构类型及使用场景详解(一)

一. 简介 Redis 是由 Salvatore Sanfilippo 编写的一个key-value存储系统&#xff0c;是跨平台的非关系型数据库。Redis是一个开源的&#xff0c;使用C语言编写的&#xff0c;遵守BSD协议&#xff0c;支持网络&#xff0c;可基于内存&#xff0c;分布式&#xff0c;可选持久性的…

EMC学习笔记(八)阻抗控制(二)

阻抗控制&#xff08;二&#xff09; 1.差分阻抗控制1.1 当介质厚度为5mil时的差分阻抗随差分线间距的变化趋势1.2 当介质厚度为13mil时的差分阻抗随差分线间距的变化趋势1.3 当介质厚度为25mil时的差分阻抗随差分线间距的变化趋势 2.屏蔽地线对阻抗的影响2.1 地线与信号线之间…

Day_54-55

目录 Day_54基于 M-distance 的推荐 一. 关于M-distance 的推荐 1. 基本数据说明 2. 推荐系统的算法过程 3. 简单思考 二. 代码复现 1. 数据导入 2. 代码的初始化 3. 核心代码 3.1 基础数据的构建 3.2 leave-out-leave测试 3.3 误差计算 Day_55基于 M-distance 的推荐 (续) …

对象的构造顺序

问题 C 中的类可以定义多个对象&#xff0c;那个对象构造的顺序是怎样的&#xff1f; 对于局部对象 当程序执行流到达对象的定义语句时进行构造 下面程序中的对象构造顺序是什么&#xff1f; 对于堆对象 当程序执行流到达 new 语句时创建对象 使用 new 创建对象将自动触发构…

python 使用 openpyxl 处理 Excel 教程

目录 前言一、安装openpyxl库二、新建excel及写入单元格1.创建一个xlsx格式的excel文件并保存2.保存成流(stream)3.写入单元格 三、创建sheet工作表及操作四、读取excel和单元格1.读取 excel 文件2.读取单元格3.获取某一行某一列的数据4.遍历所有单元格5.遍历指定行列范围的单元…

Android卡顿优化

卡顿的定义 如果在一个Vsync周期内&#xff08;60HZ的屏幕上就是16.6ms&#xff09;&#xff0c;按照整个上帧显示的执行的顺序来看&#xff0c;应用UI线程的绘制、RenderThread线程的渲染、SurfaceFlinger/HWC的图层合成以及最终屏幕上的显示这些动作没有全部都执行完成的话&…

【C语言】-- X型图案

今天刷了牛客网上的一道题&#xff0c;不难&#xff0c;但思路很重要&#xff0c;否则你就得写一长串代码&#xff0c;下面是要求。牛客网链接->X形图案。 下面是两组示例。 通过观察示例&#xff0c;我们发现输入的数字是奇数时&#xff0c;图案最中间只有一个*&#xff0c…

什么是Ajax?Ajax如何发送请求(详)

本篇来讲关于Ajax的内容&#xff0c;当然还有小伙伴可能不知道该怎么读 "Ajax"&#xff0c;它读 "阿贾克斯" &#xff0c;当然了读法可能因人而异&#xff0c;下面来进入正题&#xff0c;先来了解一下什么是Ajax&#xff1f; Ajax 是什么&#xff1f; Ajax…

魔法与现实-如何使用GPT帮我改一个万行vue代码中的BUG

开篇 传说在人类诞生之初是和魔法共存的。随时时间的流失,人们逐步开始淡忘了魔法。也有传说魔法是亚瑟王于“剑栏“一战(Battle of Camlann)后梅林永远封存了魔法使其不被心术不正者所使用。不管哪种说法,随着时间的流失,人类在飞速进步。从水利磨坊到蒸汽机的发明、再到…

Latex中表格Table环境和Tabular环境

目录 一、Table和Tabular的区别 二、一个简单的Table环境示例&#xff1a; 三、Latex的“自动换行”功能 四、Latex多行和多列 五、使用tablesgenerator快速将excel表格转换成tex代码 六、设置表格的宽度与页面宽度一致 说明:一至四内容来自Latex中使用Table&#xff08;表…

Scala入门【运算符和流程控制】

运算符 在 Scala 中其实是没有运算符的&#xff0c;所有运算符都是方法。我们只是省去了 .方法名() 中的点 . 和括号 () 。 调用对象的方法时&#xff0c;点 . 可以省略&#xff1b;如果函数参数只有一个&#xff0c;或者没有参数&#xff0c;括号()可以省略。 //num1 n…