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

Spring Boot中@Valid 与 @Validated 注解的详解

Spring Boot中@Valid 与 @Validated 注解的详解

引言

在Spring Boot应用中,参数校验是确保数据完整性和一致性的重要手段。@Valid和@Validated注解是Spring Boot中用于参数校验的两个核心注解。本文将详细介绍这两个注解的用法、区别以及代码样例。

@Valid注解
功能介绍

@Valid是Java EE提供的标准注解,它是JSR 303规范的一部分,主要用于Hibernate Validation等场景。在Spring Boot中,@Valid注解用于触发参数校验,确保请求参数的合法性。

使用场景

@Valid注解可以用于方法参数、构造函数、方法参数和成员属性上。它主要用于嵌套校验,即对于对象中的属性值(可能是另一个对象)进行校验。

代码样例
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.Valid;

public class User {
    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotNull(message = "密码不能为空")
    private String password;

    @Valid
    private Address address;

    // Getter 和 Setter
}

public class Address {
    @NotBlank(message = "国家不能为空")
    private String country;

    @NotBlank(message = "城市不能为空")
    private String city;

    // Getter 和 Setter
}

import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @PostMapping("/addUser")
    public String addUser(@Valid @RequestBody User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "参数校验失败: " + bindingResult.getAllErrors().get(0).getDefaultMessage();
        }
        return "用户添加成功";
    }
}

在上述代码中,User类中的address属性使用了@Valid注解,表示对address对象进行嵌套校验。在UserController中,addUser方法使用了@Valid注解对传入的User对象进行校验,并使用BindingResult捕获校验错误。

@Validated注解
功能介绍

@Validated是Spring框架特有的注解,属于Spring的一部分,也是JSR 303的一个变种。它提供了一些@Valid所没有的额外功能,比如分组验证。@Validated注解可以用在类、方法和方法参数上,但不能用于成员属性。

使用场景

@Validated注解主要用于支持分组验证,可以更细致地控制验证过程。此外,由于它是Spring专有的,因此可以更好地与Spring的其他功能(如Spring的依赖注入)集成。

代码样例
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.groups.Default;

public interface ValidationGroups {
    interface Insert extends Default {}
    interface Update {}
}

public class Project {
    @NotBlank(message = "ID不能为空", groups = ValidationGroups.Update.class)
    private String id;

    @NotBlank
    private String name;

    @Min(value = 1, message = "预算不能小于1", groups = ValidationGroups.Insert.class)
    private int budget;

    // Getter 和 Setter
}

import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.validation.annotation.Validated;

@RestController
public class ProjectController {

    @PostMapping("/insertProject")
    public String insertProject(@Validated(value = ValidationGroups.Insert.class) @RequestBody Project project, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "参数校验失败: " + bindingResult.getAllErrors().get(0).getDefaultMessage();
        }
        return "项目插入成功";
    }

    @PostMapping("/updateProject")
    public String updateProject(@Validated(value = ValidationGroups.Update.class) @RequestBody Project project, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "参数校验失败: " + bindingResult.getAllErrors().get(0).getDefaultMessage();
        }
        return "项目更新成功";
    }
}

在上述代码中,我们定义了一个ValidationGroups接口,用于分组验证。Project类中的id属性在Update分组下必填,而budget属性在Insert分组下必填且不能小于1。在ProjectController中,insertProject方法使用@Validated(value = ValidationGroups.Insert.class)注解对传入的Project对象进行Insert分组的校验,而updateProject方法则使用@Validated(value = ValidationGroups.Update.class)注解进行Update分组的校验。

@Valid与@Validated的区别
  1. 嵌套校验:@Valid支持嵌套校验,而@Validated不支持。在需要嵌套校验的场景下,应使用@Valid。
  2. 分组校验:@Validated支持分组校验,而@Valid不支持。在需要根据不同场景应用不同校验规则的情况下,应使用@Validated。
  3. 使用范围:@Valid可以用在方法、构造函数、方法参数和成员属性上,而@Validated只能用在类、方法和方法参数上。
结论

@Valid和@Validated注解在Spring Boot的参数校验中扮演着重要角色。掌握这两个注解的用法和区别,可以帮助开发者更灵活地进行参数校验,确保数据的完整性和一致性。

相关文章:

  • macOS 终端优化
  • 使用DeepSeek+蓝耘快速设计网页简易版《我的世界》小游戏
  • 从0到1:JavaScript小白进阶之路
  • mapbox-gl的Popup的使用详解
  • 旋转位置编码(3)
  • HarmonyOS
  • Spring Boot 项目中使用责任链模式实现复杂接口解耦和动态编排(带示例)
  • 前端技术百宝箱
  • Tweak Power:全方位电脑系统优化的高效工具
  • MySQL 与 MongoDB 的区别
  • CAN总线协议攻防实战:从漏洞分析到攻击模拟
  • 衣联网的商品列表页面结构是怎样的?
  • 设计基于锁的并发数据结构_第六章_《C++并发编程实战》笔记
  • 新一代开源数字供应链安全审查与治理平台:悬镜源鉴SCA
  • 版本控制泄露源码 .svn
  • 机器学习数学基础:45.多重响应分析
  • 鸿蒙应用开发-轻松获取http网络请求
  • 【从零开始学习计算机科学】操作系统(七)文件管理
  • Vue3 Pinia 符合直觉的Vue.js状态管理库
  • Trae AI 辅助修复uniapp 微信小程序的Bug
  • 慢品巴陵,看总编辑眼中的岳阳如何书写“山水人文答卷”
  • 中科院合肥物质院迎来新一届领导班子:刘建国继续担任院长
  • 媒体评教师拎起学生威胁要扔下三楼:师风师德不能“悬空”
  • 人民日报和音:相信中国就是相信明天
  • 俄外长与美国务卿通电话,讨论俄美接触等问题
  • 林诗栋/蒯曼混双取胜,国乒赢得多哈世乒赛开门红