SpringBoot如何优雅的处理校验参数的方法

前言

做web开发有一点很烦人就是要校验参数,基本上每个接口都要对参数进行校验,比如一些格式校验 非空校验都是必不可少的。如果参数比较少的话还是容易 处理的一但参数比较多了的话代码中就会出现大量的IF ELSE就比如下面这样:

这个例子只是校验了一下空参数。如果需要验证邮箱格式和手机号格式校验的话代码会更多,所以介绍一下validator通过注解的方式进行校验参数。

什么是Validator

Bean Validation是Java定义的一套基于注解的数据校验规范,目前已经从JSR 303的1.0版本升级到JSR 349的1.1版本,再到JSR 380的2.0版本(2.0完成于2017.08),已经经历了三个版本 。在SpringBoot中已经集成在 starter-web中,所以无需在添加其他依赖。

注解介绍

validator内置注解

注解

详细信息

@Null

被注释的元素必须为 null

@NotNull

被注释的元素必须不为 null

@AssertTrue

被注释的元素必须为 true

@AssertFalse

被注释的元素必须为 false

@Min(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@DecimalMin(value)

被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@DecimalMax(value)

被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@Size(max, min)

被注释的元素的大小必须在指定的范围内

@Digits (integer, fraction)

被注释的元素必须是一个数字,其值必须在可接受的范围内

@Past

被注释的元素必须是一个过去的日期

@Future

被注释的元素必须是一个将来的日期

@Pattern(value)

被注释的元素必须符合指定的正则表达式

Hibernate Validator 附加的 constraint

注解

详细信息

@Email

被注释的元素必须是电子邮箱地址

@Length

被注释的字符串的大小必须在指定的范围内

@NotEmpty

被注释的字符串的必须非空

@Range

被注释的元素必须在合适的范围内

@NotBlank

验证字符串非null,且长度必须大于0

注意:

  • @NotNull 适用于任何类型被注解的元素必须不能与NULL
  • @NotEmpty 适用于String Map或者数组不能为Null且长度必须大于0
  • @NotBlank 只能用于String上面 不能为null,调用trim()后,长度必须大于0

使用

使用起来也非常简单,下面略过创建项目

模拟用户注册封装了一个UserDTO

当提交数据的时候如果使用以前的做法就是IF ELSE判断参数使用validator则是需要增加注解即可。

例如非空校验:

然后需要在controller方法体添加@Validated不加@Validated校验会不起作用

然后请求一下请求接口,把Email参数设置为空

参数:

{
  "userName":"luomengsun",
  "mobileNo":"11111111111",
  "sex":1,
  "age":21,
  "email":""
}

返回结果:

后台抛出异常

这样是能校验成功,但是有个问题就是返回参数并不理想,前端也并不容易处理返回参数,所以我们添加一下全局异常处理,然后添加一下全局统一返回参数这样比较规范。

添加全局异常

创建一个GlobalExceptionHandler类,在类上方添加@RestControllerAdvice注解然后添加以下代码:

  /**
   * 方法参数校验
   */
@ExceptionHandler(MethodArgumentNotValidException.class)
public ReturnVO handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
    log.error(e.getMessage(), e);
    return new ReturnVO().error(e.getBindingResult().getFieldError().getDefaultMessage());
  }

此方法主要捕捉MethodArgumentNotValidException异常然后对异常结果进行封装,如果需要在自行添加其他异常处理。

添加完之后我们在看一下运行结果,调用接口返回:

{
  "code": "9999",
  "desc": "邮箱不能为空",
  "data": null
}

OK 已经对异常进行处理。

校验格式

如果想要校验邮箱格式或者手机号的话也非常简单。

校验邮箱

  /**
   * 邮箱
   */
  @NotBlank(message = "邮箱不能为空")
  @NotNull(message = "邮箱不能为空")
  @Email(message = "邮箱格式错误")
  private String email;

使用正则校验手机号

校验手机号使用正则进行校验,然后限制了一下位数

  /**
   * 手机号
   */
  @NotNull(message = "手机号不能为空")
  @NotBlank(message = "手机号不能为空")
  @Pattern(regexp ="^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误")
  @Max(value = 11,message = "手机号只能为{max}位")
  @Min(value = 11,message = "手机号只能为{min}位")
  private String mobileNo;

查看一下运行结果

传入参数:

{
  "userName":"luomengsun",
  "mobileNo":"111111a",
  "sex":1,
  "age":21,
  "email":"1212121"
}

返回结果:

{
  "code": "9999",
  "desc": "邮箱格式错误",
  "data": null
}

这里不再验证手机号的例子

自定义注解

上面的注解只有这么多,如果有特殊校验的参数我们可以使用Validator自定义注解进行校验

首先创建一个IdCard注解类

@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = IdCardValidator.class)
public @interface IdCard {

  String message() default "身份证号码不合法";

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};

}

在UserDTO中添加@IdCard注解即可验证,在运行时触发,本文不对自定义注解做过多的解释,下篇文章介绍自定义注解

  • message 提示信息
  • groups 分组
  • payload 针对于Bean

然后添加IdCardValidator 主要进行验证逻辑

上面调用了is18ByteIdCardComplex方法,传入参数就是手机号,验证身份证规则自行百度

然后使用

  @NotNull(message = "身份证号不能为空")
  @IdCard(message = "身份证不合法")
  private String IdCardNumber;

分组

就比如上面我们定义的UserDTO中的参数如果要服用的话怎么办?

在重新定义一个类然后里面的参数要重新添加注解?

Validator提供了分组方法完美了解决DTO服用问题

现在我们注册的接口修改一下规则,只有用户名不能为空其他参数都不进行校验

先创建分组的接口

public interface Create extends Default {
}

我们只需要在注解加入分组参数即可例如:

 /**
   * 用户名
   */
  @NotBlank(message = "用户姓名不能为空",groups = Create.class)
  @NotNull(message = "用户姓名不能为空",groups = Create.class)
  private String userName;

  @NotBlank(message = "邮箱不能为空",groups = Update.class)
  @NotNull(message = "邮箱不能为空",groups = Update.class)
  @Email(message = "邮箱格式错误",groups = Update.class)
  private String email;

然后在修改Controller在@Validated中传入Create.class

  @PostMapping("/user")
  public ReturnVO userRegistra(@RequestBody @Validated(Create.class) UserDTO userDTO){
    ReturnVO returnVO = userService.userRegistra(userDTO);
    return returnVO ;
  }

然后调用传入参数:

{
  "userName":"",
}

返回参数:

{
  "code": "9999",
  "desc": "用户姓名不能为空",
  "data": null
}

OK 现在只对Create的进行校验,而Updata组的不校验,如果需要复用DTO的话可以使用分组校验

校验单个参数

在开发的时候一定遇到过单个参数的情况,在参数前面加上注解即可

  @PostMapping("/get")
  public ReturnVO getUserInfo(@RequestParam("userId") @NotNull(message = "用户ID不能为空") String userId){
    return new ReturnVO().success();
  }

然后在Controller类上面增加@Validated注解,注意不是增加在参数前面。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Springboot使用@Valid 和AOP做参数校验及日志输出问题

    项目背景 最近在项目上对接前端的的时候遇到了几个问题 1.经常要问前端要请求参数 2.要根据请求参数写大量if...else,代码散步在 Controller 中,影响代码质量 3.为了解决问题1,到处记日志,导致到处改代码 解决方案 为了解决这类问题,我使用了@Valid 做参数校验,并使用AOP记录前端请求日志 1.Bean实体类增加注解 对要校验的实体类增加注解,如果实体类中有List结构,就在List上加@Valid @Valid注解 注解 备注 @Null 只能为null @NotNu

  • SpringBoot中通过实现WebMvcConfigurer参数校验的方法示例

    在Spring5.0和SpringBoot2.0中废弃了WebMvcConfigurerAdapter类. 现有两种解决方案 1 直接实现WebMvcConfigurer (官方推荐) 2 直接继承WebMvcConfigurationSupport 本篇文章讨论下使用第一种方式完成参数校验. 首先附上代码. @Slf4j @Controller @RequestMapping("/goods") public class GoodsController { @Autowired Mi

  • spring boot validation参数校验实例分析

    本文实例讲述了spring boot validation参数校验.分享给大家供大家参考,具体如下: 对于任何一个应用而言在客户端做的数据有效性验证都不是安全有效的,这时候就要求我们在开发的时候在服务端也对数据的有效性进行验证. Spring Boot自身对数据在服务端的校验有一个比较好的支持,它能将我们提交到服务端的数据按照我们事先的约定进行数据有效性验证. 1 pom依赖 <dependency> <groupId>org.springframework.boot</gr

  • Spring boot进行参数校验的方法实例详解

    Spring boot开发web项目有时候我们需要对controller层传过来的参数进行一些基本的校验,比如非空.整数值的范围.字符串的长度.日期.邮箱等等.Spring支持JSR-303 Bean Validation API,可以方便的进行校验. 使用注解进行校验 先定义一个form的封装对象 class RequestForm { @Size(min = 1, max = 5) private String name; public String getName() { return n

  • Spring Boot 参数校验的具体实现方式

    1.背景介绍 开发过程中,后台的参数校验是必不可少的,所以经常会看到类似下面这样的代码 这样写并没有什么错,还挺工整的,只是看起来不是很优雅而已. 接下来,用Validation来改写这段 2.Spring Boot文档中的Validation 在Spring Boot的官网中,关于Validation只是简单的提了一句,如下 其实,Spring Validator和Hibernate Validator是两套Validator,可以混着用,这里我们用Hibernate Validator 3.

  • Spring Boot实现通用的接口参数校验

    本文介绍基于 Spring Boot 和 JDK8 编写一个 AOP ,结合自定义注解实现通用的接口参数校验. 缘由 目前参数校验常用的方法是在实体类上添加注解,但对于不同的方法,所应用的校验规则也是不一样的,例如有一个 AccountVO 实体: public class AccountVO { private String name; // 姓名 private Integer age; // 年龄 } 假设存在这样一个业务:用户注册时需要填写姓名和年龄,用户登陆时只需要填写姓名就可以了.那

  • Springboot集成JSR303参数校验的方法实现

    JSR303 是一套 JavaBean 参数校验的标准 1.pom导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> 2.注解类型 (1)空检查 @Null 验证对象是否为null @NotNull 验证对象是否不为null,

  • 详解如何在Spring Boot项目使用参数校验

    开发web项目有时候我们需要对controller层传过来的参数进行一些基本的校验,比如非空,非null,整数值的范围,字符串的个数,日期,邮箱等等.最常见的就是我们直接写代码校验,这样以后比较繁琐,而且不够灵活. Bean Validation 1.0(JSR-303)是一个校验规范,在spring Boot项目由于自带了hibernate validator 5(http://hibernate.org/validator/)实现,所以我们可以非常方便的使用这个特性 . 核心的pom依赖:

  • springboot+dubbo+validation 进行rpc参数校验的实现方法

    注意:本文dubbo 版本 2.8.4 springboot 版本 2.0.4.RELEASE 项目结构 test-rest (前端消费着,controller 层,springboot+maven项目) test-api (dubbo服务 的 api ,只记录 service 接口和 model ,maven 项目) test-provider(dubbo 服务提供者,实际的数据库操作及业务层, springboot+maven项目 ) 背景: 使用springmvc做restful,使用du

  • SpringBoot如何优雅的处理校验参数的方法

    前言 做web开发有一点很烦人就是要校验参数,基本上每个接口都要对参数进行校验,比如一些格式校验 非空校验都是必不可少的.如果参数比较少的话还是容易 处理的一但参数比较多了的话代码中就会出现大量的IF ELSE就比如下面这样: 这个例子只是校验了一下空参数.如果需要验证邮箱格式和手机号格式校验的话代码会更多,所以介绍一下validator通过注解的方式进行校验参数. 什么是Validator Bean Validation是Java定义的一套基于注解的数据校验规范,目前已经从JSR 303的1.

  • SpringBoot 中使用 Validation 校验参数的方法详解

    目录 1. Validation 介绍 1.1 Validation 注解 1.2 @valid 和 @validated的区别 2. SpringBoot 中使用 Validator 校验参数 2.1 依赖引入 2.2 标注校验实体类 2.3 开启参数校验 2.3.1 简单参数校验 2.3.2 JavaBean 校验 2.4 捕捉参数校验异常 项目中写逻辑时,为保证程序的健壮性,需要对各种参数进行判断,这就导致业务代码不只健壮,还十分臃肿.其实 SpringBoot 中已经提供了 Valida

  • SpringBoot利用validation实现优雅的校验参数

    目录 1.前言 2.常用校验 3.spring boot的数据自动校验功能 3.1 引入依赖 3.2 构建启动类 3.3 创建需要被校验的实体类 3.4 在Controller中校验数据 3.5 统一异常处理 4.自定义校验注解 4.1 @NameValidation 4.2 校验类NameValidationValidator 4.3 在Person类增加新注解 5.总结 1.前言 数据的校验是交互式网站一个不可或缺的功能,前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱

  • springboot使用hibernate validation对参数校验的实现方法

    springboot天生支持使用hibernate validation对参数的优雅校验,如果不使用它,只能对参数挨个进行如下方式的手工校验,不仅难看,使用起来还很不方便: if(StringUtils.isEmpty(userName)){ throw new RuntimeException("用户名不能为空"); } 下面将介绍hibernate validation的基本使用方法. 一.引入依赖 这里在springboot 2.4.1中进行实验,引入以下依赖: <pare

  • Springboot如何优雅地进行字段校验

    差不多大半年没写文章了,终于将手头上的事忙完了,可以对外输出了.前段时间提交代码审核,同事提了一个代码规范缺陷:参数校验应该放在controller层.到底应该如何做参数校验呢 Controller层 VS Service层 去网上查阅了一些资料,一般推荐与业务无关的放在Controller层中进行校验,而与业务有关的放在Service层中进行校验.那么如何将参数校验写的优雅美观呢,如果都是if - else,就感觉代码写的很low,还好有轮子可以使用 常用校验工具类 使用Hibernate V

  • 如何使用Spring Validation优雅地校验参数

    引言 不知道大家平时的业务开发过程中 controller 层的参数校验都是怎么写的?是否也存在下面这样的直接判断? public String add(UserVO userVO) { if(userVO.getAge() == null){ return "年龄不能为空"; } if(userVO.getAge() > 120){ return "年龄不能超过120"; } if(userVO.getName().isEmpty()){ return &q

  • SpringBoot集成validation校验参数遇到的坑

    公众号中分享了一篇文章,关于SpringBoot集成validation校验参数的,粉丝留言说有坑. 原留言如下: 有坑,你试试^A-\\d{12}-\\d{4}$,这条正则经过validate这个方法无论参数写的对不对都会报验证错误,而用main方法测试是正常的.. 话说,针对这种回复我是不太信了,直觉告诉我,肯定是这位粉丝用错了.但既然粉丝有疑问还是需要专门写一个demo来验证一下的.说写就写. SpringBoot集成validation 集成过程非常简单,在原项目的pom文件中直接引入如

  • 一篇文章带了解如何用SpringBoot在RequestBody中优雅的使用枚举参数

    目录 确认需求 定义枚举和对象 实现转换逻辑 方案一:精准攻击 方案二:全范围攻击 测试 总结 确认需求 需求与前文类似,只不过这里需要是在 RequestBody 中使用.与前文不同的是,这种请求是通过 Http Body 的方式传输到后端,通常是 json 或 xml 格式,Spring 默认借助 Jackson 反序列化为对象. 同样的,我们需要在枚举中定义 int 类型的 id.String 类型的 code,id 取值不限于序号(即从 0 开始的 orinal 数据),code 不限于

  • Springboot 如何使用BindingResult校验参数

    目录 使用BindingResult校验参数 1.创建一个参数对象 2.controller控制层写参数接收的入口 3.传入参数和控制台打印结果 4.常用校验注解 BindingResult 作用原理 使用BindingResult校验参数 1.创建一个参数对象 import java.util.List; import javax.validation.constraints.Min; import javax.validation.constraints.Size; import org.h

随机推荐