注解式参数校验@Valid,拒绝if-else炼狱

2024-01-09 04:52

本文主要是介绍注解式参数校验@Valid,拒绝if-else炼狱,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

        在软件开发中,与客户进行数据的交互是比较频繁的数据采集方式,而为了确保数据的正确落库,数据校验的部分必不可少。参数校验具体指的是对输入数据的大小、类型、正则匹配等对数据本身属性的校验,这一块的校验通常是在前端进行第一轮校验,确保参数具备一定逻辑正确性才将其打包至后端处理,而为了进一步增强安全性,也同样需要在后端板块进行二次校验。而对于此类校验,最常见也是最臃肿的处理方案就是if-else炼狱,如果说参数个数较少,那么无可厚非,但如果包含了七八个参数,那么这就很拉跨了,下面介绍一种基于注解的校验方案,进一步优化校验参数代码的可读性。


效果演示

本例子基于通过在实体类映射接收请求参数的MVC接口,对实体类中需要对属性进行如下验证:

  • name - 用户姓名,不能为空;

  • age - 年龄,大于0小于20;

  • phone - 手机号,满足手机号格式;

实体类代码

 @Datapublic class TestPojo {@NotBlank(message = "不满足时抛出的自定义异常回馈信息")private String name;@Min(value = 0, message = "不满足时抛出的自定义异常回馈信息")@Max(value = 20, message = "不满足时抛出的自定义异常回馈信息")private Integer age;@Pattern(regexp = "^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(147))\d{8}$", message = "不满足时抛出的自定义异常回馈信息")private String phone;}

业务接口

@PostMapping("/test")
public ResultVO test(@Valid @RequestBody TestPojo testPojo) {// 直接写业务代码,无需编写if-else校验....return ResultVO.ok("响应数据");}

结果VO类

@Data
public class ResultVO<T> implements Serializable {private int code;private boolean success;private T data;private String msg;
​private ResultVO(int code, T data, String msg) {this.code = code;this.data = data;this.msg = msg;this.success = code == 200;}
​public static <T> ResultVO<T> ok(T data) {return new ResultVO<>(200, data, null);}
​public static <T> ResultVO<T> error(String msg) {return new ResultVO<>(500, null, msg);}
}

全局异常处理类

@RestControllerAdvice
public class GlobalExceptionHandler {/*  *  这里的BindException不是自定义的,是该参数校验框架自带的*  当设置的参数规则不满足,就会抛出该类型的异常,并且把不满足的哪个校验参数自定义的异常信息封装到该对象中*/@ExceptionHandler(BindException.class)  public ResultVO handleError(BindException e) {BindingResult bindingResult = e.getBindingResult();return R.error(bindingResult.getFieldError().getDefaultMessage());}
}

        通过以上代码,就可以实现对接收的请求数据的参数校验,并且当校验失败就会抛出指定异常被异常处理类进行捕捉处理,返回自定义的不满足参数所对应的自定义提示信息


快速使用

引入依赖

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

编写校验实体类

        其实这一块和上方"结果VO类"的演示中可以了解到使用的方式,咱主要要知道它有哪些常用的校验注解可以使用就好

常用注解作用解释
@NotNull值不能为null
@NotEmpty字符串、集合或数组的值不能为空,即长度大于0
@NotBlank字符串的值不能为空白,即不能只包含空格
@Size字符串、集合或数组的大小是否在指定范围内
@Min数值的最小值
@Max数值的最大值
@DecimalMin数值的最小值,可以包含小数
@DecimalMax数值的最大值,可以包含小数
@Pattern字符串是否匹配指定的正则表达式

还有许多有关的校验可以自行查询,这里不作过多赘述

校验失败异常捕获处理

@RestControllerAdvice
public class GlobalExceptionHandler {/*  *  这里的BindException不是自定义的,是该参数校验框架自带的*  当设置的参数规则不满足,就会抛出该类型的异常,并且把不满足的哪个校验参数自定义的异常信息封装到该对象中*/@ExceptionHandler(BindException.class)  public ResultVO handleError(BindException e) {BindingResult bindingResult = e.getBindingResult();String 自定义的不满足参数校验结果信息 = bindingResult.getFieldError().getDefaultMessage();}
}

启用校验

其实就是在接收实体类上加一个@Valid注解就可以启用实体类中校验逻辑

@PostMapping("/test")
public void test(@Valid @RequestBody TestPojo testPojo) {// 直接写业务代码,无需编写if-else校验....}

        也许会有疑惑,一个实体类我不一定要用来校验数据呀,这样子设置后会不会以后用这个实体类都要进行参数校验了?并不会,不想校验就不要加@Valid注解就完事了嘛


总结

        通过以上的方案,我们可以较为简洁实现简单的参数校验,为shi山的削减贡献了一份力量,当然,我们会发现通过这种方案,我们能够校验的方式实际上是比较单薄的,往往我们需要针对项目业务需求对参数进行一些自定义的校验逻辑,那么这点可以参考我写的另一篇文章:基于 AOP + 自定义注解 的校验业务讲解,希望本文对大家有所帮助。

这篇关于注解式参数校验@Valid,拒绝if-else炼狱的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

Spring如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建

mapstruct中的@Mapper注解的基本用法

《mapstruct中的@Mapper注解的基本用法》在MapStruct中,@Mapper注解是核心注解之一,用于标记一个接口或抽象类为MapStruct的映射器(Mapper),本文给大家介绍ma... 目录1. 基本用法2. 常用属性3. 高级用法4. 注意事项5. 总结6. 编译异常处理在MapSt

Spring @RequestMapping 注解及使用技巧详解

《Spring@RequestMapping注解及使用技巧详解》@RequestMapping是SpringMVC中定义请求映射规则的核心注解,用于将HTTP请求映射到Controller处理方法... 目录一、核心作用二、关键参数说明三、快捷组合注解四、动态路径参数(@PathVariable)五、匹配请

SpringCloud中的@FeignClient注解使用详解

《SpringCloud中的@FeignClient注解使用详解》在SpringCloud中使用Feign进行服务间的调用时,通常会使用@FeignClient注解来标记Feign客户端接口,这篇文章... 在Spring Cloud中使用Feign进行服务间的调用时,通常会使用@FeignClient注解

Java 关键字transient与注解@Transient的区别用途解析

《Java关键字transient与注解@Transient的区别用途解析》在Java中,transient是一个关键字,用于声明一个字段不会被序列化,这篇文章给大家介绍了Java关键字transi... 在Java中,transient 是一个关键字,用于声明一个字段不会被序列化。当一个对象被序列化时,被

Python FastAPI实现JWT校验的完整指南

《PythonFastAPI实现JWT校验的完整指南》在现代Web开发中,构建安全的API接口是开发者必须面对的核心挑战之一,本文将深入探讨如何基于FastAPI实现JWT(JSONWebToken... 目录一、JWT认证的核心原理二、项目初始化与环境配置三、安全密码处理机制四、JWT令牌的生成与验证五、

Spring Cache注解@Cacheable的九个属性详解

《SpringCache注解@Cacheable的九个属性详解》在@Cacheable注解的使用中,共有9个属性供我们来使用,这9个属性分别是:value、cacheNames、key、key... 目录1.value/cacheNames 属性2.key属性3.keyGeneratjavascriptor

使用@Cacheable注解Redis时Redis宕机或其他原因连不上继续调用原方法的解决方案

《使用@Cacheable注解Redis时Redis宕机或其他原因连不上继续调用原方法的解决方案》在SpringBoot应用中,我们经常使用​​@Cacheable​​注解来缓存数据,以提高应用的性能... 目录@Cacheable注解Redis时,Redis宕机或其他原因连不上,继续调用原方法的解决方案1