初探Springboot 参数校验

文章目录

  • 前言
  • Bean Validation
    • 注解
  • 实践出真知
    • 异常处理
  • 总结

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

前言

工作中我们经常会遇到验证字段是否必填,或者字段的值是否在给定范围之内等等类似的问题,如果说是一两个字段的验证还好,验证的字段很多的话,代码就会被大量的if语句包围。通常来说,这些关于字段的判断应该和业务逻辑分开来,可能我们想到的第一个解决方案就是通过AOP,这也能解决我们的问题的。但实际上大可不必,作为一个成熟的语言,Java已经给我们提供解决方案了,那就是Bean Validation

Bean Validation

JSR-303是Java EE 6中的一项子规范,名为Bean Validation,这是Bean Validation 1.0 版本,目前已发展到到3.0版本,名为Jakarta Bean Validation 3.0。Bean Validation提供了一个数据验证的框架,用于对Java Bean中的字段的值进行验证。它使得基本的验证逻辑可以从业务代码中脱离出来,成为一个独立的验证层。

JSR-303的官方参考实现是Hibernate ValidatorHibernate Validator提供了JSR 303规范中所有内置约束的实现,除此之外还有一些附加的约束。

这种验证机制是运行时的,也就是说,在验证之后,如果数据不符合指定的约束,那么会立即返回错误信息。

总之,JSR-303 为Java应用程序提供了一种方便、灵活且强大的数据验证方式。

注解

JSR-303 提供了一系列注解,用于在Java中进行数据校验。这些注解主要用于对实体类的属性进行约束,以确保数据的有效性。

在这里插入图片描述

以下是一些常用的JSR-303 validation注解:

  1. @NotNull:用于对象的校验,确保对象不为null
  2. @NotBlank:验证对象是否不为空,相比@NotNull会去掉首尾空格,对象类型为CharSequence
  3. @NotEmpty: 验证对象(如数组、Collection集合、MapString)是否不为NULL并且长度或者大小不为空
  4. @Size:用于验证对象(如数组、Collection集合、MapString)的长度或大小是否在给定的范围之内。
  5. @Pattern:验证字符串是否匹配指定的正则表达式,null值被认为是有效的格式。
  6. @Email:验证是否符合电子邮件格式。
  7. @Min:验证数字是否大于等于指定值,
  8. @Max:验证数字是否小于等于指定值。
  9. @AssertTrue:验证Boolean对象是否为true。
  10. @AssertFalse:验证Boolean对象是否为false。
  11. @NotBlank:验证CharSequence 对象非null,且长度必须大于0。
  12. @DecimalMin(value):被注解的对象必须是一个数字,其值必须大于等于指定的最小值,对象类型可以为 BigDecimalBigIntegerCharSequence
  13. @DecimalMax:被注解的对象必须是一个数字,其值必须小于等于指定的最大值。
  14. @Digits(integer,fraction):被注解的元素必须是一个数字,其值必须在指定的整数和小数部分的最大位数的范围之内。
  15. @Past:被注解的元素必须是一个过去的日期。
  16. @Future:被注解的元素必须是一个将来的日期。
  17. @FutureOrPresent:被注解的元素必须是现在或将来的一个瞬间、日期或时间。
  18. @PositiveOrZero:被注解的元素必须为正数或零。
  19. @Positive:被注解的元素必须是正数(不包括0)。
  20. @NegativeOrZero:被注解的元素必须为负数或零。
  21. @Negative:被注解的元素必须是负数(不包括0)。
  22. @Null:被注解的元素必须是NULL

Hibernate Validator 附加的约束注解:
Hibernate Validator 8.0.1官方链接 感兴趣的可以去看看。

Hibernate Validator 8.0.1

实践出真知

下面通过代码演示一下Springboot 中字段验证的使用。

1. 引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
</dependency>

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

2. 创建Bean 用于校验

@Data
public class UserBean {

    
    @NotEmpty
    private String username;

    @Min(value = 18)
    private Integer age;

   @Email(message = "邮箱格式不正确")
    private String email;
}

3. 创建访问接口

接口中要使用 @Validated 或者 @Valid使Bean 验证生效,下一篇文章 @Validated@Valid 之间的区别。

@RestController
@RequestMapping("validation")
public class ValidationController {

    @GetMapping("user")
    public UserBean getUserBean(@Validated UserBean userBean) {
        return userBean;
    }
}

4. 使用postman进行测试

因为username校验不通过,所以postman响应结果如下,响应结果不够友好,下面会进行改造:

{
    "timestamp": "2024-02-28T09:15:23.925+00:00",
    "status": 400,
    "error": "Bad Request",
    "path": "/validation/user"
}

控制台打印结果比较详细:

2024-02-28T17:15:23.918+08:00  WARN 24752 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : 
Resolved [org.springframework.web.bind.MethodArgumentNotValidException:
 Validation failed for argument [0] in public site.suncodernote.validation.UserBean 
 site.suncodernote.validation.ValidationController.getUserBean(site.suncodernote.validation.User
 Bean): [Field error in object 'userBean' on field 'username': rejected value [null]; codes 
 [NotEmpty.userBean.username,NotEmpty.username,NotEmpty.java.lang.String,NotEmpty]; arguments 
 [org.springframework.context.support.DefaultMessageSourceResolvable: codes 
 [userBean.username,username]; arguments []; default message [username]]; default message [不能为空]] ]

异常处理

由于默认的校验提示不够友好,无法具体显示是哪个字段出现的问题,下面我们将其简单改造一下。

1. 封装统一响应对象

@Data
public class ResponseResult <T> implements Serializable {

    private boolean success;

    /**
     * 返回处理消息
     */
    private String message;

    /**
     * 返回代码
     */
    private Integer code = 0;

    /**
     * 返回数据对象 data
     */
    private T result;
}

2. 封装全局异常处理类

@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     *  参数校检异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseResult<?> handle(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();

        StringJoiner joiner = new StringJoiner(";");

        for (ObjectError error : bindingResult.getAllErrors()) {
            // 注解名称
            String code = error.getCode();
            String[] codes = error.getCodes();

            String property = codes[1];
            property = property.replace(code ,"").replace(".","");

            String defaultMessage = error.getDefaultMessage();
            joiner.add(property+defaultMessage);
        }
        return handleException(joiner.toString());
    }

    private ResponseResult<?> handleException(String msg) {
        ResponseResult<?> result = new ResponseResult<>();
        result.setMessage(msg);
        result.setCode(500);
        return result;
    }
}

GlobalExceptionHandler 异常处理类中,为了省事就把字段名和验证失败提示语拼接到一起了。

3. 再次测试

再次测试可以看到在响应结果中得到了我们想要的结果了,至此Springboot参数校验入门就完成了。

总结

Springboot 参数校验在实际工作中用处非常大,本文只是简单介绍一下有哪些注解和简单使用,后续会对Springboot参数校验做一个详细的介绍和使用,感兴趣可以关注一下。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Python人工智能] 四十三.命名实体识别 (4)利用bert4keras构建Bert+BiLSTM-CRF实体识别模型

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解如何实现中文命名实体识别研究,构建BiGRU-CRF模型实现。这篇文章将继续以中文语料为主,介绍融合Bert的实体识别研究,使用bert4keras和kears包来构建Bert+BiLSTM-CRF模型。然而,该代码最终结…

轻松解锁微博视频:基于Perl的下载解决方案

引言 随着微博成为中国最受欢迎的社交平台之一&#xff0c;其内容已经变得丰富多彩&#xff0c;特别是视频内容吸引了大量用户的关注。然而&#xff0c;尽管用户对微博上的视频内容感兴趣&#xff0c;但却面临着无法直接下载这些视频的难题。本文旨在介绍一个基于Perl的解决方…

Unity Toggle处理状态变化事件

Toggle处理状态变化事件&#xff0c;有两个方法。 法一、通过Inspector面板设置 实现步骤&#xff1a; 在Inspector面板中找到Toggle组件的"On Value Changed"事件。单击""按钮添加一个新的监听器。拖动一个目标对象到"None (Object)"字段&am…

pytorch单层感知机

目录 1.单层感知机模型2. 推导单层感知机梯度3. 实战 1.单层感知机模型 2. 推导单层感知机梯度 公式前加了一个1/2是为了消除平方2&#xff0c;不加也是可以的&#xff0c;不会改变函数的单调性 3. 实战 初始化1行10列的x和wsigmod中xw.t() w做了转置操作是为了将[1,10]转换…

webpack5零基础入门-12搭建开发服务器

1.目的 每次写完代码都需要手动输入指令才能编译代码&#xff0c;太麻烦了&#xff0c;我们希望一切自动化 2.安装相关包 npm install --save-dev webpack-dev-server 3.添加配置 在webpack.config.js中添加devServer相关配置 /**开发服务器 */devServer: {host: localhos…

[OpenCV学习笔记]获取鼠标处图像的坐标和像素值

目录 1、介绍2、效果展示3、代码实现4、源码展示 1、介绍 实现获取鼠标点击处的图像的坐标和像素值&#xff0c;灰度图显示其灰度值&#xff0c;RGB图显示rgb的值。 OpenCV获取灰度值及彩色像素值的方法&#xff1a; //灰度图像&#xff1a; image.at<uchar>(j, i) //j…

.NET 异步编程(异步方法、异步委托、CancellationToken、WhenAll、yield)

文章目录 异步方法异步委托async方法缺点CancellationTokenWhenAllyield 异步方法 “异步方法”&#xff1a;用async关键字修饰的方法 异步方法的返回值一般是Task<T>&#xff0c;T是真正的返回值类型&#xff0c;Task<int>。惯例&#xff1a;异步方法名字以 Asy…

【保姆级】前端使用node.js基础教程

文章目录 安装和版本管理&#xff1a;npm 命令&#xff08;Node 包管理器&#xff09;&#xff1a;运行 Node.js 脚本&#xff1a;调试和开发工具&#xff1a;其他常用命令&#xff1a;模块管理&#xff1a;包管理&#xff1a;调试工具&#xff1a;异步编程和包管理&#xff1a…

redis和rabbitmq实现延时队列

redis和rabbitmq实现延时队列 延迟队列使用场景Redis中zset实现延时队列Rabbitmq实现延迟队列 延迟队列使用场景 1. 订单超时处理 延迟队列可以用于处理订单超时问题。当用户下单后&#xff0c;将订单信息放入延迟队列&#xff0c;并设置一定的超时时间。如果在超时时间内用户…

数据仓库系列总结

一、数据仓库架构 1、数据仓库的概念 数据仓库&#xff08;Data Warehouse&#xff09;是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合&#xff0c;用于支持管理决策。 数据仓库通常包含多个来源的数据&#xff0c;这些数据按照主题进行组织和存储&#x…

AnyGo for Mac最新激活版:位置模拟软件打破地域限制

AnyGo for Mac&#xff0c;一款专为Mac用户打造的位置模拟软件&#xff0c;让您能够轻松打破地域限制&#xff0c;畅享无限可能。 软件下载&#xff1a;AnyGo for Mac v7.0.0最新激活版 通过AnyGo&#xff0c;您可以随时随地模拟出任何地理位置&#xff0c;无论是国内热门景点还…

【Godot4.2】2D导航02 - AstarGrid2D及其使用方法

概述 AstarGrid2D是Godot4.0新增的A*寻路辅助类型。可以看做是Astar2D的加强版。它允许你通过设置其size和cell_size属性来创建一个虚拟的网格。 并使用set_point_solid()这样的方法来在指定位置创建障碍物。 AstarGrid2D的好处是你不再需要手动的添加点以及点与点之间的连接…

vue3+element Plus form 作为子组件,从父组件如何赋值?

刚开始接触vue3时&#xff0c;碰到一个很low的问题&#xff0c;将form作为子组件&#xff0c;在页面中给form表单项输入内容&#xff0c;输入框不显示值&#xff0c;知道问题出在哪&#xff0c;但因为vue3组合式api不熟悉&#xff0c;不知从哪下手... 效果图&#xff1a; 父组…

ubuntu下samba匿名读写服务器

目的&#xff1a; 局域网内&#xff0c;ubuntu下&#xff0c;创建SAMBA文件共享服务器。匿名读写权限。为了开发项目组文件共享传输方便。 环境&#xff1a; X86_64电脑一台。 操作系统&#xff1a; Ubuntu 20.04 LTS 64位。 安装samba $ sudo apt-get install samba创建…

FPGA通过I2C控制AT24C64

文章目录 前言一、代码设计框图二、IIC_drive模块设计2.1、模块接口&#xff1a;2.2、代码功能描述&#xff1a;2.3、IIC协议实现过程&#xff1a; 三、EEPROM_ctrl模块设计3.1、模块接口&#xff1a;3.2、代码功能描述 四、EEPROM_drive模块五、iic_top模块 前言 继上一篇FPG…

计算机毕业设计-基于深度学习的验证码识别方法设计与实现

概要 验证码是一个系统区分人类与非人类行为的有效方式。验证码识别技术能够使计算机程序输入正确的验证码&#xff0c;伪装成人类用户进入目标系统。另一方面&#xff0c;系统方面需要考虑破解验证码识别技术&#xff0c;修补验证方式的可能漏洞&#xff0c;使之能够更有效地区…

[Uni-app] 微信小程序的圆环进度条

效果图&#xff1a; 组件完整代码如下&#xff1a; <template><view class"base-style":style"position: relative;width: diameter px;height: diameter px;display: flex;flex-direction: row;background-color: bgColor ;"><!…

RK3588+FPGA+AD+AI的智能数据采集与分析解决方案

RK3588是瑞芯微新一代旗舰级高端处理器&#xff0c;具有高算力、低功耗、超强多媒体、丰富数据接口等特点。搭载四核A76四核A55的八核CPU和ARM G610MP4 GPU&#xff0c;内置6.0TOPs算力的NPU。 RK3588复旦微FPGA方案 有五大技术优势 1. 内置多种功能强大的嵌入式硬件引擎&…

【Linux(1)】Linux的一些基本指令(补充上一篇)

思维导图 学习内容 通过上面的学习目标&#xff0c;我们可以列出要学习的内容&#xff1a; linux的一些指令&#xff1a;cd mkdir cp touch which rm cat alias 一些基本的概念&#xff1a;指令的概念&#xff0c;用户家目录是什么...... 一、Linux的一些指令 1.1 重新认识…

基于Spring Boot共享单车信息系统的设计与实现

摘 要 快速发展的社会中&#xff0c;人们的生活水平都在提高&#xff0c;生活节奏也在逐渐加快。为了节省时间和提高工作效率&#xff0c;越来越多的人选择利用互联网进行线上打理各种事务&#xff0c;然后线上管理系统也就相继涌现。与此同时&#xff0c;人们开始接受方便的生…