SpringBoot注解--06--注解@Validated

news2024/9/22 17:20:52

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 1 简述
    • 1.1 @Validated作用
    • 1.2 所有参数注解含义
    • 1.3 异常处理
    • 1.4 @Valid和@Validated比较
      • @Valid级联校验
  • 2.@Validated 分组校验
    • 1.1为何要分组校验?
    • 1.2 代码案例
    • 1.3 @Validated分组校验顺序
        • 分组校验顺序通过==使用 @GroupSequence注解==实现
  • 3.@Validated的使用方法
    • 3.1 在方法级别上使用@Validated
    • 3.2 在==类级别==上使用@Validated
    • 3.2 Get请求参数校验


1 简述

  • @Validated是Spring框架中的一个注解,它是JSR-303规范的扩展,可以用于在方法级别上校验方法参数。
  • 它可以用于验证请求参数和请求体中的数据。@Validated注解可以用于方法级别和类级别上,用于验证方法参数和类属性。

1.1 @Validated作用

@Validation是一套帮助我们继续对传输的参数进行数据校验的注解,通过配置Validation可以很轻松的完成对数据的约束

  • @Validated作用在类、方法和参数上

在这里插入图片描述

1.2 所有参数注解含义

在这里插入图片描述

1.3 异常处理

错误的状态码:返回的响应码推荐使用400 bad request.

说明:若不做异常处理,@Validated注解的默认异常消息如下(示例):

2020-09-05 21:48:38.106  WARN 9796 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : 
Resolved [org.springframework.web.bind.MethodArgumentNotValidException: 
Validation failed for argument [0] in public java.lang.String com.example.validateddemo.controller.DemoController.validatedDemo1(com.example.validateddemo.entity.dto.UseDto):
 [Field error in object 'useDto' on field 'username': rejected value [null]; 
 codes [NotBlank.useDto.username,NotBlank.username,NotBlank.java.lang.String,NotBlank]; 
 arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [useDto.username,username]; arguments []; 
 default message [username]]; default message [用户名不能为空!]] ]
package com.example.validateddemo.handler;
 
import com.example.validateddemo.base.Result;
import com.example.validateddemo.enums.ResultEnum;
import com.example.validateddemo.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.util.List;
 

@Slf4j
@ControllerAdvice
public class ValidatedExceptionHandler {
 
    /**
     * 处理@Validated参数校验失败异常
     * @param exception 异常类
     * @return 响应
     */
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result exceptionHandler(MethodArgumentNotValidException exception){
        BindingResult result = exception.getBindingResult();
        StringBuilder stringBuilder = new StringBuilder();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            if (errors != null) {
                errors.forEach(p -> {
                    FieldError fieldError = (FieldError) p;
                    log.warn("Bad Request Parameters: dto entity [{}],field [{}],message [{}]",fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
                    stringBuilder.append(fieldError.getDefaultMessage());
                });
            }
        }
        return ResultUtil.validatedException(stringBuilder.toString());
    }
}

1.4 @Valid和@Validated比较

Spring Boot–09–注解@Valid

在这里插入图片描述

  • @Valid支持级联校验,而@Validated不行
  • @Validated支持分组校验,而@Valid不行

@Valid级联校验

级联校验: 也叫嵌套检测.嵌套就是一个实体类包含另一个实体类
@Valid和可以用在成员属性的字段上,因此 @Valid可以提供级联校验

@Data
public class Hair {
	
	@NotBlank(message = "头发长度必须提交!")
	private Double length;
 
  	@NotBlank(message = "头发颜色必须提交!")
  	private String color;
}
 
@Data
public class Person {
	
	@NotBlank(message = "用户姓名必须提交!")
	@Size(min=2, max=8)
	private String userName;
 
  	// 添加@Valid注解实现嵌套检测
  	@Valid
    @NotEmpty(message = "用户要有头发!")
    private List<Hair> hairs;
}
 
@PostMapping("/person")
public Result addPerson(@Valid @RequestBody Person person) {
	return Result.buildSuccess(person);
}

只是在方法参数前面添加 @Valid和 @Validated注解,不会对嵌套的实体类进行校验.要想实现对嵌套的实体类进行校验,需要在嵌套的实体类属性上添加 @Valid注解

2.@Validated 分组校验

1.1为何要分组校验?

假设有这样一种场景:

我们使用同一个VO(Request)类来传递save和update方法的数据,

  • 但对于save方法来说,通常有框架帮我们生成id,我们不需要传id此时需要使用注解@Null表名id数据必须为空。
  • 但对于update方法,我们必须传id才能进行update操作,所以同一个字段面对不同的场景不同需求就可以使用分组校验。

1.2 代码案例

(1)创建分组接口
这里并不需要实现编写什么代码,标明分类。

//分组接口 1
public interface InsertGroup {
}

//分组接口 2
public class UpdateGroup {
}

(2)Request实体类

@Data
@NoArgsConstructor
public class TestRequest {

    @Null(message = "无需传id",groups = InsertGroup.class)
    @NotBlank(message = "必须传入id",groups = UpdateGroup.class)
    private String id;
    
  }

(3)controller接口

	@RequestMapping("/valid/test")
    public ResponseEntity<ResponseResult> test(@Validated({UpdateGroup.class})@RequestBody TestRequest request) {
        System.out.println(request);
        return null;
    }

(4)postman测试
在这里插入图片描述
(5)注意事项!!!
当我们在controller层指定分组后,属性上没有表名分组的校验还执行么?

下面的Request实体中,id进行了分组,address没有进行分组:

@Data
@NoArgsConstructor
public class TestRequest {

    @Null(message = "无需传id",groups = InsertGroup.class)
    @NotBlank(message = "必须传入id",groups = UpdateGroup.class)
    private String id;

	@Length(max = 3, message = "address最大长度是3")
    private String address;
    
  }

postman测试:

如下图,校验没有成功!!!!说明一旦开启了分组校验,就必须把所有的校验规则都指定组别,不然不生效

在这里插入图片描述

1.3 @Validated分组校验顺序

默认情况下,分组间的约束是无序的,但是在一些特殊的情况下可能对分组间的校验有一定的顺序

  • 比如第二组的分组的约束的校验需要依赖第一组的稳定状态来进行,此时,要求分组间的约束校验一定要有顺序
分组校验顺序通过使用 @GroupSequence注解实现
@Data
public class UserGroupSequence {
	
	public interface FirstGroup {}
 
	public interface SecondGroup {}
 
	// 使用GroupSequence定义分组校验顺序:按照FirstGroup,SecondGroup分组顺序进行校验
	@GroupSequence({FirstGroup.class, SecondGroup.class})
	public interface Group {}
 
	@NotEmpty(message = "用户ID必须提交!", group = FirstGroup.class)
	private String userId;
 
	@NotEmpty(message = "用户姓名必须提交!", group = FirstGroup.class)
	@Size(min = 2, max = 8, message = "用户姓名的长度在2~8之间", goup = Second.class)
	private String userName;
} 

Controller

@RestController
@RequestMapping("/user")
public class UserGroupSequenceController {
	// 这里方法中@Validated注解value的值是Group.class
	@PostMapping("/user")
	public Result addGroup(@Validated(value = Group.class) @RequestBody UserGroupSequence user) {
		return Result.buildSuccess(user);
	}
}

使用 @GroupSequence注解指定分组校验顺序后,第一组分组的约束的校验没有通过后,就不会进行第二组分组的约束的校验

3.@Validated的使用方法

3.1 在方法级别上使用@Validated

在方法级别上使用@Validated注解,需要在方法参数上添加该注解。下面是一个简单的示例,演示了如何在方法级别上使用@Validated注解。

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

在上面的示例代码中,@Validated注解被应用在User对象上,用于验证请求体中的数据是否符合要求。

3.2 在类级别上使用@Validated

在类级别上使用@Validated注解,需要在类上添加该注解。下面是一个简单的示例,演示了如何在类级别上使用@Validated注解。

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

在上面的示例代码中,@Validated注解被应用在UserController类上,用于验证该类中所有方法的参数是否符合要求

3.2 Get请求参数校验

get参数校验,需要在类上加@Validated

@RestController
@Slf4j
@RequestMapping("/api/test")
@Validated
public class TestController {
    @GetMapping(value = "/h11")
    public String test11( @NotEmpty(message = "姓名不能为空") String name) {
 
        System.out.println("kaidsd");
        System.out.println(name);
 
        return "applyInfoDTO";
    }
}

在这里插入图片描述

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

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

相关文章

ERP 系统架构的设计与实践总结

企业资源计划&#xff08;ERP&#xff09;系统是一种集成多个业务功能的综合性软件解决方案。在设计和实践 ERP 系统架构时&#xff0c;需要考虑诸多因素&#xff0c;以确保系统能够满足企业的需求&#xff0c;并提供高效、可靠、安全的服务。本文将介绍一些关键的设计原则和实…

2023年全球软件开发大会(QCon上海站2023):核心内容与学习收获(附大会核心PPT下载)

在信息化和全球化日益加速的今天&#xff0c;软件开发技术日新月异&#xff0c;对全球各行各业产生了深远影响。2023年全球软件开发大会&#xff08;QCon上海站2023&#xff09;无疑成为行业内外瞩目的焦点。本次大会汇集了全球顶级的软件开发专家、企业领袖、研究者&#xff0…

Filter与Listener(Java Web)

Filter与Listener(Java Web) 概念&#xff1a;Filter表示过滤器&#xff0c;是JavaWeb三大组件(Servlet、Filter、Listener)之一。过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能。过滤器一般完成一些通用的操作&#xff0c;比如&#xff1a;权限控制、…

Hudi学习 6:Hudi使用

准备工作&#xff1a; 1.安装hdfs https://mp.csdn.net/mp_blog/creation/editor/109689143 2.安装spark spark学习4&#xff1a;spark安装_hzp666的博客-CSDN博客 3.安装Scala Hudi学习6&#xff1a;安装和基本操作_hzp666的博客-CSDN博客 spark-shell 写入和读取hudi 2.…

鸿蒙应用开发-自定义可删除列表弹窗

功能介绍&#xff1a; 自定义列表弹窗&#xff0c;可以对弹窗的列表点击删除&#xff0c;参考文档创建列表&#xff0c;自定义弹窗文档自定义弹窗&#xff08;CustomDialog&#xff09;。 知识点&#xff1a; 熟悉对List控件的使用。熟悉对List点击删除熟悉自定义弹窗。 使…

2024美赛C题完整解题教程及代码 网球运动的势头

2024 MCM Problem C: Momentum in Tennis &#xff08;网球运动的势头&#xff09; 注&#xff1a;在网球运动中&#xff0c;"势头"通常指的是比赛中因一系列事件&#xff08;如连续得分&#xff09;而形成的动力或趋势&#xff0c;这可能对比赛结果产生重要影响。球…

【Unity知识点详解】自定义程序集

今天来介绍一下Unity中的自定义程序集。在项目开发中我们经常接触到第三方插件的程序集&#xff0c;如DOTween、Newtonsoft.Json等。 使用自定义程序集有这么几个好处&#xff1a; 方便代码的的复用。当某一功能模块需要在多个项目中重复使用时&#xff0c;可以将代码编译成程…

canvas设置图形各种混合模式,类似photoshop效果

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

树莓派zero/zero w的区别

直观区别 1、zero没有WiFi和蓝牙模块&#xff0c;当然也没有网线接口&#xff0c;适合不需要网络的场景需求。 2、zero w带有WiFi和蓝牙模块&#xff0c;没有网线接口。适合需要网络的场景需求。 选购建议 我一般都是看有没有网络接口或者WiFi支持&#xff08;一定要选择焊接…

未来电话呼叫技术的社会影响与发展趋势----云微呼

未来电话呼叫技术将以更为智能化、便捷化和个性化为主要发展趋势&#xff0c;其所带来的社会影响也将是多层面的。以下将探讨未来电话呼叫技术可能的发展趋势以及对社会的影响&#xff1a; 智能化助力生活便捷&#xff1a; 未来电话呼叫技术将更加智能化&#xff0c;通过人工智…

《计算机网络简易速速上手小册》第10章:未来网络技术趋势(2024 最新版)

文章目录 10.1 边缘计算与网络设计 - 未来网络的速度与激情10.1.1 基础知识10.1.2 重点案例&#xff1a;使用 Python 实现边缘计算的实时视频分析准备工作Python 脚本示例 10.1.3 拓展案例1&#xff1a;智能交通系统Python 脚本示例 - 边缘计算设备上的交通流量分析 10.1.4 拓展…

牛客网 OR76 两个整数二进制位不同个数

前提需备知识&#xff1a; 算法&#xff1a;n&&#xff08;n-1&#xff09;是用来求n中1的个数 常用代码形式为&#xff1a; while(n){count;nn&(n-1); //每次减去1的个数} 关于该算法的推导可以见http://t.csdnimg.cn/Tld2S&#xff0c;本文就不再赘述 思路&…

三种pdf转ppt方法?学会这几招轻松搞定转换

三种pdf转ppt方法&#xff1f;在当今的工作和生活中&#xff0c;PDF和PPT这两种文件格式常常会让我们感到困扰。有时候我们需要将PDF文件转换成PPT格式&#xff0c;以便更好地进行演示或工作汇报。但是&#xff0c;如何快速、准确地完成这项任务呢&#xff1f;本文将为你揭秘三…

4.java中的输入输出/输入中的next和nextLine区别问题

&#xff08;笔试会经常让我们自己去处理输入输出&#xff09; 一.输出到控制台 println 输出的内容自带 \n&#xff08;换行&#xff09; print 不带 \n printf 的格式化输出方式和 C 语言的 printf 是基本一致的. String msg "Hello, World!";System.out.print(m…

非常好看的CSS加载中特效,引用css文件既可用

非常好看的CSS加载中特效 demo效果源码&#xff1a; <!DOCTYPE html5> <head><link rel"stylesheet" type"text/css" href"demo.css"/><link rel"stylesheet" type"text/css" href"loaders.css&…

C语言内存分配函数知识汇总

C语言中的主要内存分配函数包括&#xff1a; 1. malloc() - 函数原型&#xff1a;void *malloc(size_t size) - 功能&#xff1a;动态分配指定大小&#xff08;以字节为单位&#xff09;的连续内存空间。 - 返回值&#xff1a;成功分配内存时&#xff0c;返回指向该内存区域…

力扣热门100题刷题笔记 - 3.无重复字符的最长子串

力扣热门100题 - 3.无重复字符的最长子串 题目链接&#xff1a;3. 无重复字符的最长子串 题目描述&#xff1a; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。示例&#xff1a; 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字…

全球降水数据产品介绍

一、数据基本概况 降水数据在气象学、水文学、农业、生态学等领域有着广泛的用途。以下是一些降水数据的主要用途&#xff1a; 气象预报和监测&#xff1a; 降水数据是气象预报的重要组成部分&#xff0c;对预测天气、气候和自然灾害&#xff08;如暴雨、洪水&#xff09;至关…

Python学习从0到1 day13 Python数据容器.4.set集合、dict字典,映射

他往黑夜里去了&#xff0c;我陪他 ——24.2.4 一、set集合 1.为什么使用集合&#xff1f; 通过特性来分析&#xff1a; 列表可修改、支持重复元素且有序 元组、字符串不可修改、支持重复元素且有序 局限在于&#xff1a;它们都支持重复元素 当场景需要对内容进行去重处理&am…

微分几何——梅向明第四版学习笔记(一) 向量函数和曲线论

目录 引出向量函数曲线论简单曲线定义曲线的向量参数表示 曲线的切线【重要】曲线的法面【重要】曲线的自然参数表示 空间曲线曲线的密切平面空间曲线的基本三棱形【重要】单位切向量主法向量副法向量Frenet标架螺旋线的案例 曲线的曲率和曲率半径曲率的几何意义 曲线的挠率挠率…