spring-boot---validation,参数校验,分组,嵌套,各种类型

2023-09-21 20:26:57
写在前面:
参数校验基本上是controller必做的事情,毕竟前端传过来的一切都不可信。 但是每次if(StrUtil.isNotNull())啥的有时候多还难写。validation可以简化这一操作。

项目构建

采用boot3,主要依赖为spring web 和validation
在这里插入图片描述

主要依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

项目结构
在这里插入图片描述

问题展示

先来个简单的案例

@RestController
public class ValidationController {

    @GetMapping("/get")
    public String get(String name,String age){
        System.out.println(name);
        System.out.println(age);
        return "ok";
    }
}

点击这个就可以发送请求了
在这里插入图片描述
发送出去不会做任何校验
在这里插入图片描述
这个的处理我们可以选择加上@RequestParam注解。
@RequestParam默认属性require为true,就是必须要传值,

 public String get(@RequestParam String name,@RequestParam String age)

报错返回
在这里插入图片描述
封装成实体类也是一样的。

但是这样只能做非null判断,不能做复杂的判断。
在body里面的时候更加不会校验了
在这里插入图片描述

validation使用

那么validation又如何做到呢。

快速入门

需求:get请求中,name长度在2-10,age在10-100岁之间且都不为null。

    @GetMapping("/get")
    public String get(@Length(max = 10,min = 2) String name,
                      @Min(10)@Max(100) String age){
        System.out.println("name = " + name);
        System.out.println("age = " + age);
        return "ok";
    }

为null发送,好ok一点用没有。
在这里插入图片描述
我查资料发现需要参数前面加上启动校验@Validated或者@Valid注解,但是无论我怎么放到都是没有校验。
全部无效。
在这里插入图片描述
我之前研究了半天,然后才发现,如果想要这样校验的话,需要在controller类上面加上@Validated且Valid都不行。
在这里插入图片描述
如果是实体类接收就不一样了。
直接在方法就可以了
在这里插入图片描述

注释

到这里基本使用应该就差不多知道了。
现在来进行注解的学习。

注解通用属性
基本上都有的

属性描述
message错误返回描述
groups分组,可以进行更加灵活的选择。
payload

无参注解,无必须传的值

注解限制类型
@Null限制只能为null接收任何类型,这个应该用的比较少
@NotNull限制必须不为null接收任何类型
@AssertFalse限制必须为false支持的类型包括 boolean 和 Boolean。null 元素被视为有效。
@AssertTrue限制必须为true支持的类型包括 boolean 和 Boolean。null 元素被视为有效。
@Future限制必须是一个将来的日期大部分的时间类如果Date、Calendar、Instant、LocalDate等。null 元素被视为有效
@Past限制必须是过去的时刻、日期或时间和上面一样
@PastOrPresent带注释的元素必须是过去或现在的时刻、日期或时间同上
@NotEmpty带批注的元素不得为 null和空CharSequence(计算字符序列的长度)Collection (集合大小)Map (大小)数组(计算数组长度)
@NotBlank带批注的元素不得且 null 必须至少包含一个非空格字符CharSequence
@Positive带注释的元素必须是严格的正数(即 0 被视为无效值)。BigDecimal、BigInteger、byteintlong、 short及其floatdouble各自的包装器
@PositiveOrZero正数或0同上

大小注解,用于限值大小

注解限制类型
@DecimalMax(value,inclusive)限制必须为一个不大于指定值的value数字,inclusive:指定指定的最小值是包含的还是排除的true为不包括最小值BigDecimal、BigInteger、CharSequence、byte、 shortintlong及其各自的包装器,请注意, double 由于舍入错误,不支持 (某些 float 提供程序可能会提供一些近似支持)。null 元素被视为有效。
@DecimalMin(value,inclusive)限制必须为一个不小于指定值的value数字,inclusive:最大值是否包括同上
@Digits(integer,fraction)必须是接受范围内的数字,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction同上
@Max(value)限制必须为一个不大于指定值的数字同上
@Min(value)限制必须为一个不小于指定值的数字同上
@Length(min = 6, max = 16)指定传入的字符串的长度字符串
@Size(max,min)限制字符长度必须在min到max之间 【不是数字】同notempty,集合类数组和字符
@Range带批注的元素必须在适当的范围内。应用于数值或数值的字符串表示形式。

基于正则类型

注解限制类型
@Pattern(value)限制必须符合指定的正则表达式CharSequence,null有效
@Email验证注解的元素值是Email,可选值regexp,flags也可以通过正则表达式和flag指定自定义的email格式。因为每个人要求的邮箱可能格式也不一样,如我可以通过regexp设置后缀必须为@qq.comCharSequence,null有效
@CreditCardNumber信用卡校验同上
@URL批注的字符串是否为 URL基于正则表达式的 。同上
@UUID批注的字符序列是否为有效的 UUID,version指定版本variant变体,letterCase所需的字母大小写 默认情况下只有小写有效,allowNil如果 nil UUID 有效 根据默认值 nil UUID 00000000-0000-0000-0000-000000000000 有效,allowEmpty允许空字符串。默认情况下不允许空字符串

脚本注解
@ScriptAssert
它根据批注元素计算脚本表达式。此约束可用于实现验证例程,脚本表达式可以用任何脚本或表达式语言编写,在类路径上可以找到 JSR 223 (“JavaTM 平台脚本”)兼容引擎。下面的清单显示了使用 JDK 附带的 JavaScript 引擎的示例:
我看到的时候给我震惊了一下,他注解写的啥??任何表达式语言??不过可能是我没见过世面,或者是知识点用的少,java6就支持JavaScript。不过一般很少用吧。

下面是一个校验时间的脚本

@ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")   
public class CalendarEvent {
     private Date startDate;
     private Date endDate;
     //...
}

注意!!!java11开始就移除了NashornScriptEngineFactory,所以11以上需要添加依赖才可以使用javascript
需要新增

        <dependency>
            <groupId>org.openjdk.nashorn</groupId>
            <artifactId>nashorn-core</artifactId>
            <version>15.4</version>
        </dependency>

没有通过

在这里插入图片描述
修改时间通过了
在这里插入图片描述

Valid与Validated区别

Validated是Valid的加强版

使用范围

经过我的层层验证

  1. controller类上:
    在controller类上只有使用validated,将开启所有的路径参数验证,对实体类(路径和body)无效
  2. 方法上:
    全部无效,无论是路径还说body,2个注解都没用。
  3. 入参上:
    只有在对body或者路径参数实体类或者添加注解才有效,2个都有效,对单独的类型无效
  4. 实体类的属性上
    Valid有效,且路径参数有效,body无效,body需要自己参数开启,无论参数是否加验证注解

两者是否能用于成员属性(字段)上直接影响能否提供嵌套验证的功能。

分组

@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制。没有添加分组属性时,默认验证没有分组的验证属性。Valid是不能进行分组的,灵活性更差。

public class DemoQuery {
    @Length(max = 10, min = 2,groups = {Demo1.class, Demo2.class},message = "name长度不符合要求")
    private String name;
    @Min(value = 10,groups = {Demo1.class}) @Max(100)
    @NotNull
    private Integer age;
}

    @PostMapping("/post2")
    public String post2(@Validated({Demo2.class}) @RequestBody DemoQuery query, @NotNull String id) {
        System.out.println("name = " + query.getName());
        System.out.println("age = " + query.getAge());
        System.out.println("id = " + id);
        return "ok";
    }

不通过
在这里插入图片描述

通过
在这里插入图片描述
改为demo1
在这里插入图片描述

嵌套验证

新增一个类

@Data
public class NestedQuery {

    @NotNull
    private String id;

    @Valid
    @NotNull
    private DemoQuery querys;
}

    @GetMapping("/nested")
    public String nested(@Validated NestedQuery query, BindingResult bindingResult) {
        System.out.println("id = " + query.getId());
        System.out.println("query = " + query.getQuerys());
        System.out.println(bindingResult);
        return "ok";
    }

发送返回的居然是ok,
在这里插入图片描述
但是在控制台,验证说出错了,说明嵌套的错误不会直接返回,而是会记录。需要自己处理一下。

在这里插入图片描述

Assert.isTrue(!bindingResult.hasErrors(),"参数错误");

在这里插入图片描述
结束:收工,累死了。

更多推荐

快速了解Apipost

随着数字化转型的加速,API(应用程序接口)已经成为企业间沟通和数据交换的关键。而在API开发和管理过程中,API文档、调试、Mock和测试的协作显得尤为重要。Apipost正是这样一款一体化协作平台,旨在解决这些问题,提高API开发效率和质量。Apipost提供API文档管理功能,让后端开发人员可以在开发完接口调试的

cookie信息无法获取问题研究

背景在oneapi这个前后端都有的开源项目中,我想接入chatnextweb到oneapi的后端。由于需要二开chatnextweb,添加登录注册功能,考虑到java后端的性能问题和内存占用,决定不重启写个服务,而是将登录注册接入到oneapi的登录注册api,没错,和oneapi的前端公用一套登录注册熬了个大夜后,终

GLTF编辑器:在线模型材质编辑工具

GLTF编辑器是一个功能强大、易于使用的在线3D模型编辑和查看工具,它支持多种格式的3D模型导入并将模型导出为GLB格式,除了可以对3D模型进行基本属性的修改之外,还支持对模型原点重置以及模型材质纹理修改。对于3D开发者和设计师来说,GLTF编辑器是一个非常有用的工具,可以帮助他们更方便地处理3D模型数据。1、首先介绍

VR全景技术在教育中的应用:VR教学的“因材施教”

随着科技的不断进步和发展,VR全景技术在教育领域的应用,给传统教育模式带来了新的变革和机遇,同时也促进了教育的创新和进步。VR教学模式可以打破传统教育的限制,通过模拟各种场景,让学生身临其境地学习多样化知识,感受不同国家的风土人情、拓展自身视野,这种具备沉浸感的学习体验可以很好的激发学生的学习兴趣和动力。VR教学可以构

vr飞机驾驶舱模拟流程3D仿真演示加大航飞安全法码

众所周知,航空航天飞行是一项耗资大、变量参数很多、非常复杂的系统工程,因此可利用虚拟仿真技术经济、安全及可重复性等特点,进行飞行任务或操作的模拟,以代替某些费时、费力、费钱的真实试验或者真实试验无法开展的场合,从而获得提高航空航天员工作效率或航空航天器系统可靠性等的设计对策。飞机飞行操作要求严、风险大且成本高,因此在真

windows RocketMQ与可视化监控平台安装

windowsRocketMQ与可视化监控平台安装安装日期2023.09.21最新版RocketMQ是一个纯Java、分布式、队列模型的开源消息中间件,搭建RocketMQ需要先配置JAVA环境变量,需要有JAVA_HOME。下载安装包进入官网选择需要的版本下载安装包(以下以5.1.3为例)。官网下载地址:官网下载编译

中秋节听夜曲,Android OpenGL 呈现周董专属的玉兔主题音乐播放器

概述前几天发现QQ音乐有个好玩的功能,为用户提供了多种播放器主题,其中原神的主题让我眼前一亮:当然,诸如换肤、主题类的功能已经屡见不鲜,但这类沉浸式播放器的听歌体验确实不错。见猎心喜,正好中秋马上就到,我也尝试整个中秋主题音乐播放器试试水。整体思路有2点:首先是技术方面,纯粹的ImageView图层堆砌来实现,渲染效率

05预测识别-依托YOLO V8进行训练模型的识别——对视频中的图片进行识别

在前面的一些章节中,我们已经讲如何准备打标签的素材、如何制作标签、如何训练以及得到我们最终需要的用于YOLO目标识别的模型。那么现在我们就要正式开始,利用我们训练得到的best.pt,这个模型文件来对图片视频进行识别。1、基本思路公安交管场景中,我们经常会遇到需要对摄像头拍到的视频中的目标进行识别,比如识别识别非机动车

【C++】C++ 引用详解 ③ ( 函数返回值不能是 “ 局部变量 “ 的引用或指针 | 函数内的 “ 局部变量 “ 的引用或指针做函数返回值无意义 )

文章目录一、函数返回值不能是"局部变量"的引用或指针1、引用通常做右值2、函数返回值特点3、函数内的"局部变量"的引用或指针做函数返回值无意义二、代码示例-"局部变量"引用或指针做函数返回值测试一、函数返回值不能是"局部变量"的引用或指针1、引用通常做右值之前使用引用时,都是作为右值使用,引用只在声明的同时进行初始化时

ChatGPT可以取代搜索引擎吗?

目录ChatGPT可以取代搜索引擎吗?1、功能和应用场景2、处理的信息量3、实时性4、准确性5、使用习惯和依赖性未来发展趋势1、搜索引擎与ChatGPT的融合2、个性化搜索与自然语言处理3、搜索引擎作为对话平台4、增强现实与搜索引擎ChatGPT是一种大规模的预训练模型,旨在生成自然语言文本,以便在各种自然语言处理任务

【2023,学点儿新Java-51】变量与运算符 (阶段性复习3):常用运算符回顾之比较运算符、逻辑运算符、条件运算符、了解位运算符

前情提要:【2023,学点儿新Java-50】阶段性章节复习:String类的使用以及与基本数据类型变量间的运算|认识进制|常用运算符回顾之算术运算符、赋值运算符【2023,学点儿新Java-49】变量与运算符(阶段性复习2):基本数据类型变量的使用,基本数据类型变量间的运算规则【2023,学点儿新Java-48】变量

热文推荐