首页 > 其他分享 >Spring Boot 实现优雅的参数校验

Spring Boot 实现优雅的参数校验

时间:2024-06-21 14:32:15浏览次数:12  
标签:验证 Spring Boot 校验 参数 是否 注解 message

前言

在日常的 Web 开发中,请求参数校验是一个非常基础且重要的环节。通过校验,我们可以确保每次接口请求中,入参的数据是有效、安全且合规的,避免数据库中出现脏数据。

手动校验参数

原始的手动校验参数代码如下:

@PostMapping("/test")
    @ApiOperationLog(description = "测试接口")
    public ResponseEntity<String> test(@RequestBody User user) {
        // 参数校验
        if (user.getName() == null || user.getName().trim().isEmpty()) {
            return ResponseEntity.badRequest().body("姓名不能为空");
        }

        if (user.getAge() < 18 || user.getAge() > 100) {
            return ResponseEntity.badRequest().body("年龄必须在18到100之间");
        }

        if (user.getEmail() == null || !isValidEmail(user.getEmail())) {
            return ResponseEntity.badRequest().body("邮箱格式不正确");
        }

        // 更多的校验...

        // 返参
        return ResponseEntity.ok("参数没有任何问题");
    }

这还是只有 3 个字段需要校验的情况,如果更多呢?一堆的 if else 是不是又臭又长!有没有什么优雅的解决方案呢?

JSR 380 参数校验注解

Spring Boot 提供了简洁的方法,让我们能够利用 Java 校验 API (JSR 380) 中定义的注解进行参数校验。JSR 380,也被称为 Bean Validation 2.0,是 Java Bean 验证规范的一个版本。该规范定义了一系列注解,用于验证 Java Bean 对象的属性,确保它们满足某些条件或限制。

以下是 JSR 380 中提供的主要验证注解及其描述:

  1. @NotNull: 验证对象值不应为 null。
  2. @AssertTrue: 验证布尔值是否为 true。
  3. @AssertFalse: 验证布尔值是否为 false。
  4. @Min(value): 验证数字是否不小于指定的最小值。
  5. @Max(value): 验证数字是否不大于指定的最大值。
  6. @DecimalMin(value): 验证数字值(可以是浮点数)是否不小于指定的最小值。
  7. @DecimalMax(value): 验证数字值(可以是浮点数)是否不大于指定的最大值。
  8. @Positive: 验证数字值是否为正数。
  9. @PositiveOrZero: 验证数字值是否为正数或零。
  10. @Negative: 验证数字值是否为负数。
  11. @NegativeOrZero: 验证数字值是否为负数或零。
  12. @Size(min, max): 验证元素(如字符串、集合或数组)的大小是否在给定的最小值和最大值之间。
  13. @Digits(integer, fraction): 验证数字是否在指定的位数范围内。例如,可以验证一个数字是否有两位整数和三位小数。
  14. @Past: 验证日期或时间是否在当前时间之前。
  15. @PastOrPresent: 验证日期或时间是否在当前时间或之前。
  16. @Future: 验证日期或时间是否在当前时间之后。
  17. @FutureOrPresent: 验证日期或时间是否在当前时间或之后。
  18. @Pattern(regexp): 验证字符串是否与给定的正则表达式匹配。
  19. @NotEmpty: 验证元素(如字符串、集合、Map 或数组)不为 null,并且其大小/长度大于0。
  20. @NotBlank: 验证字符串不为 null,且至少包含一个非空白字符。
  21. @Email: 验证字符串是否符合有效的电子邮件格式。

除了上述的标准注解,JSR 380 也支持开发者定义和使用自己的自定义验证注解。此外,这个规范还提供了一系列的APIs和工具,用于执行验证和处理验证结果。大部分现代Java框架(如 Spring 和 Jakarta EE)都与 JSR 380 兼容,并支持其验证功能。

开始动手

引入依赖

首先,我们需要在 xx-web 模块中的 pom.xml 文件添加参数校验依赖:

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

实体类参数校验

package com.yanxiaosheng.xx.web.model;

import lombok.Data;

import javax.validation.constraints.*;

/**
 * @author: 闫小生
 * @url: www.yanxiaosheng.com
 * @date: 2023-08-10 10:35
 * @description: TODO
 **/
@Data
public class User {
    // 用户名
    @NotBlank(message = "用户名不能为空") // 注解确保用户名不为空
    private String username;
    // 性别
    @NotNull(message = "性别不能为空") // 注解确保性别不为空
    private Integer sex;

    // 年龄
    @NotNull(message = "年龄不能为空")
    @Min(value = 18, message = "年龄必须大于或等于 18")  // 注解确保年龄大于等于 18
    @Max(value = 100, message = "年龄必须小于或等于 100")  // 注解确保年龄小于等于 100
    private Integer age;

    // 邮箱
    @NotBlank(message = "邮箱不能为空")
    @Email(message = "邮箱格式不正确")  // 注解确保邮箱格式正确
    private String email;
}

上述代码说明:

  • @NotBlank: 此注解确保字符串不为空并且不能为空字符串,且去掉前后空格后的长度必须大于 0。它常用于字符串字段验证。message 属性用于指定提示信息;
  • @NotNull: 此注解确保整数类型不能为 null
  • @Min 和 @Max: 这两个注解用于验证数字值是否在指定的范围内。例如,在上面的示例中,我们想要确保 age 的值在 18 到 100 之间;
  • @Email: 此注解用于验证字符串值是否是有效的电子邮件地址格式。

Controller 参数校验

针对每个字段的校验注解添加完成后,还需要在 controller 层进行捕获,并将错误信息返回。编辑 TestController 类,代码如下:

@RestController
@Slf4j
public class TestController {

    @PostMapping("/test")
    @ApiOperationLog(description = "测试接口")
        public ResponseEntity<String> test(@RequestBody @Validated User user, BindingResult bindingResult) {
        // 是否存在校验错误
        if (bindingResult.hasErrors()) {
            // 获取校验不通过字段的提示信息
            String errorMsg = bindingResult.getFieldErrors()
                    .stream()
                    .map(FieldError::getDefaultMessage)
                    .collect(Collectors.joining(", "));

            return ResponseEntity.badRequest().body(errorMsg);
        }

        // 返参
        return ResponseEntity.ok("参数没有任何问题");
    }

}

解释一下上面代码中的关键部分:

  • @Validated: 告诉 Spring 需要对 User 对象执行校验;
  • BindingResult : 验证的结果对象,其中包含所有验证错误信息;

测试一下效果

使用 Postman 工具请求 /test 接口测试一下,请求入参如下:

入参正确的情况

入参:

{
    "username": "闫小生",
    "sex": 1,
    "age": 32,
    "email": "[email protected]"
}

入参不正确的情况

入参数据:

{
    "username": "",
    "sex": null,
    "age": 120,
    "email": "123124qq.com"
}

可以看到,在字段不符合校验规则的情况下,正确返回了每个字段的提示信息。参数校验功能正常执行。

标签:验证,Spring,Boot,校验,参数,是否,注解,message
From: https://blog.csdn.net/m0_68207804/article/details/139823912

相关文章

  • Spring常用注解,自动扫描装配Bean
    1引入context命名空间(在Spring的配置文件中),配置文件如下:Xml代码xmlns:context="http://www.springframework.org/schema/context"http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd......
  • 计算机Java项目|SpringBoot在线宠物用品交易网站
    作者主页:编程指南针作者简介:Java领域优质创作者、CSDN博客专家、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师主要内容:Java项目、Python项目、前端项目、人工智能与大数据、简历模板、学习资料、面试题库、技术互......
  • Modbus协议ASCII模式下数据的LRC校验
          Modbus协议ASCII模式下数据的LRC校验,计算校验时不包括开头的冒号字符,从第2个字符开始。计算LRC时先将原始的ASCII码格式的数据转换为HEX(ASCII码格式数据‘F’转换为0x0F);在将转换后的HEX数据按照高半字节在前低半字节在后的顺序(如a[1]=0x0F,a[2]=0x0A,合并后的数......
  • spring整合openAI大模型之Spring AI
    文章目录一、SpringAI简介1.什么是SpringAI2.SpringAI支持的大模型类型(1)聊天模型(2)文本到图像模型(3)转录(音频到文本)模型(4)嵌入模型(5)矢量数据库3.SpringAI版本二、SpringAI框架使用,对接OpenAI1.环境信息2.初始化3.配置文件(1)application.yml(2)pom文件4.聊天代码测试(1)聊天接......
  • 「Java开发指南」如何使用Spring注释器实现Spring控制器?(二)
    本教程将引导您使用SpringAnnotator实现Spring控制器,标准Java类被添加到搭建项目中,SpringAnnotatorSpring启用Java类。虽然本教程的重点是Spring控制器,但是SpringAnnotator也可以用于Spring服务、组件和存储库。在本教程中,您将学习如何:创建一个Java类将类配置为Spring控制......
  • springMVC域对象共享数据
    目录五、域对象共享数据5.1、使用ServletAPI向request域对象共享数据5.2、使用ModelAndView向request域对象共享数据5.3、使用Model向request域对象共享数据5.4、使用map向request域对象共享数据5.5、使用ModelMap向request域对象共享数据5.6Model、ModelMap、Map的关系5.7、向se......
  • Springboot+Vue+Mybatis-Plus+Easyexcel实现文件导入+导出的excel单元格下拉列表
    引言文件的导入与导出功能扮演着至关重要的角色,特别是在处理大量数据和复杂的表格时。通过整合SpringBoot、Vue、Mybatis-Plus和Easyexcel等先进技术,我们可以构建一个高效、灵活的文件处理系统。其中,Excel作为广泛使用的电子表格软件,其单元格下拉列表功能对于数据录入和校验......
  • 使用Sentinel进行服务调用的熔断和限流管理(SpringCloud2023实战)
    你好,这里是codetrend专栏“SpringCloud2023实战”。本文简单介绍SpringCloud2023中使用Sentinel进行限流管理。前言随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控......
  • Spring的一些思考(一)
    new一个对象和依赖注入一个对象的区别?new一个对象时,直接使用关键字new来创建实例。这个对象的生命周期由自己来管理,可以实现对对象的细粒度的控制依赖注入是创建对象的另一种方式。DI可以减轻耦合,生命周期由Spring来负责,只需配置该对象和它依赖的对象如何配置即可DI的优......
  • 三级缓存---解决 Spring 循环依赖
    1.循环依赖1.1什么是循环依赖首先,什么是循环依赖?这个其实好理解,就是两个Bean互相依赖,类似下面这样:“”"@ServicepublicclassAService{ @Autowired BServicebService;}@ServicepublicclassBService{ @Autowired AServiceaService;}“”"AServic......