Spring-Validation 后端数据校验的实现

前言

最近看到很多童鞋在项目中的对请求参数的校验都用的if来判断各参数的属性,如:

if(StringUtils.isBlank(username)){
  return RR.exception("账号不能为空");
}

if(StringUtils.isBlank(password)){
  return RR.exception("密码不能为空");
}

if(StringUtils.isBlank(realName)){
  return RR.exception("姓名不能为空");
}
......

每个参数都需要这样一个个去校验null,返回对应信息,代码就像叠罗汉一样~~,在此,楼主强烈推荐一个神器:Validation,有了它,再也不用这样去校验参数啦,可以让我们在项目中不用太关注其他东西,专注于业务逻辑的编写。

引入核心依赖

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

使用示例-添加用户

需要校验的实体类,在此使用了一些常用的校验注解,基本上能够见名知意,每个注解中都有message属性,就是校验不通过后的提示信息

@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "Account", description = "用户实体类")
public class Account implements Serializable {

  private static final long serialVersionUID = -6310331730721778951L;

  private Long id;

  @NotBlank(message = "用户名不能为空")
  @Length(max = 10, message = "用户名最长为10位")
  private String name;

  @Pattern(regexp = PatternUtil.PASSWORDREGEX, message = "密码为6-20位数字加字母组合")
  private String pwd;

  @NotBlank(message = "姓名不能为空")
  @Length(max = 8, message = "姓名最长为8位")
  private String realName;

  @Pattern(regexp = PatternUtil.PHONENOREGEX, message = "手机号码格式不正确")
  private String phone;

  @NotNull(message = "用户性别不能为空")
  @Max(value = 1,message = "性别 0:男 1:女")
  @Min(value = 0,message = "性别 0:男 1:女")
  private Integer sex;

  @NotNull(message = "用户状态不能为空")
  @Max(value = 1,message = "用户状态 0:启用 1:禁用")
  @Min(value = 0,message = "用户状态 0:启用 1:禁用")
  private Integer status;

  @Length(max = 200, message = "备注最长为200个字符")
  private String rmk;
}
 

controller接口,注意在接收参数前需加上@Validated注解,这样就会逐个去校验实体类中需要加了校验注解的的属性,完全通过才进入下一步业务处理,否则抛出MethodArgumentNotValidException异常,在这里我们直接将异常抛出,交给全局异常处理类来处理。

@SysLog(menu = "用户管理", function = "添加",filterParams = {"pwd","password","salt"})
@PermissionCheck("account:manager:add")
@PostMapping(value = "/add", produces = BaseConsts.REQUEST_HEADERS_CONTENT_TYPE)
@ApiOperation(value = "用户管理-添加用户接口", notes = "用户管理-添加用户接口", httpMethod = BaseConsts.REQUEST_METHOD, response = RR.class)
public RR add(@Validated @RequestBody Account account) throws Exception {
  return RR.success("添加用户成功");
}

声明全局异常处理类,处理所有异常,可以随业务需要将异常种类细分,返回错误码,返回提示信息可自由定义...   这里只需关注MethodArgumentNotValidException异常。

@RestControllerAdvice
public class GlobalExceptionHandle {

  /**
   * @param e
   * @return
   * @Description 未知异常处理
   */
  @ExceptionHandler(Exception.class)
  public RR handleException(Exception e) {
    e.printStackTrace();
    return RR.exception("系统异常,请联系管理员");
  }

  /**
   * @param e
   * @return
   * @Description 请求参数异常
   */
  @ExceptionHandler(MethodArgumentNotValidException.class)
  public RR handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
    return RR.exception("请求参数错误:[" + e.getBindingResult().getFieldError().getDefaultMessage() + "]");
  }

  /**
   * @param e
   * @return
   * @Description 系统业务服务异常
   */
  @ExceptionHandler(ServerException.class)
  public RR handleServerException(ServerException e) {
    return RR.exception(e.getMessage());
  }

  /**
   * @param e
   * @return
   * @Description 令牌校验异常
   */
  @ExceptionHandler(ExpireException.class)
  public RR handleExpireException(ExpireException e) {
    return RR.expire(e.getMessage());
  }

  /**
   * @param e
   * @return
   * @Description 无权访问异常
   */
  @ExceptionHandler(AccessDeniedException.class)
  public RR handleAccessDeniedException(AccessDeniedException e) {
    return RR.forbidden(e.getMessage());
  }

  /**
   * @param e
   * @return
   * @Description 自定义重复操作异常
   */
  public RR handleRepeatHandleException(RepeatHandleException e) {
    return RR.exception("您的请求已发送,请勿重复操作!");
  }

  /**
   * @param e
   * @return
   * @Description 登录异常处理
   */
  @ExceptionHandler(AuthenticationException.class)
  public RR handleAuthenticationException(AuthenticationException e) {
    return RR.exception(e.getMessage());
  }
}

然后我们用Swagger来测试一下接口

1.用户名为空

2.手机号格式错误

通过返回结果可以看到,我们的校验注解已经帮我们按照指定的校验方式校验了指定的字段属性,我们在统一的全局异常处理类中将提示信息封装成需要的返回结果就可以了。

分组校验

有的童鞋在此可能有疑问了,上述方法虽然可行,但我在新增用户和修改用户两个接口中,新增用户的用户id是自动生成的,无需校验;修改用户的用户id是必传的,则需校验。在此业务场景中,那岂不是需要声明两个实体类,但这两个实体类中的属性又大致相同,这不是增加麻烦吗?其实不然,在此我们可以用到 groups 属性来解决此场景下的问题。

声明分组

注意:在声明分组的时候尽量加上 extend javax.validation.groups.Default 否则,在你声明@Validated(Update.class)的时候,就会出现你在默认没添加groups = {}的时候的校验组@Email(message = "邮箱格式不对"),会不去校验,因为默认的校验组是groups = {Default.class}。

/**
 * 数据新增分组
 */
public interface Create extends Default {

}

/**
 * 数据更新分组
 */
public interface Update extends Default {

}

校验注解中添加分组,groups 为一个数组,可以添加多个分组

@NotNull(message = "id不能为空" , groups = Update.class)
private Long id;

@NotBlank(message = "用户名不能为空" , groups = {Create.class, Update.class})
@Length(max = 10, message = "用户名最长为10位")
private String name;

修改Controller中的@Validated注解,声明校验分组

@PermissionCheck("account:manager:add")
@PostMapping(value = "/add", produces = BaseConsts.REQUEST_HEADERS_CONTENT_TYPE)
@ApiOperation(value = "用户管理-添加用户接口", notes = "用户管理-添加用户接口", httpMethod = BaseConsts.REQUEST_METHOD, response = RR.class)
public RR add(@Validated(Create.class) @RequestBody Account account) throws Exception {
  return RR.success("添加用户成功");
}

@PermissionCheck("account:manager:edit")
@PostMapping(value = "/edit", produces = BaseConsts.REQUEST_HEADERS_CONTENT_TYPE)
@ApiOperation(value = "用户管理-修改用户接口", notes = "用户管理-修改用户接口", httpMethod = BaseConsts.REQUEST_METHOD, response = RR.class)
public RR edit(@Validated(Update.class) @RequestBody Account account) throws Exception {
  return RR.success("编辑用户成功");
}

使用相同的请求参数测试一下添加用户和修改用户的接口

测试添加接口

测试修改接口

通过接口的返回结果可以看到,新增用户的接口并没有校验id这个参数了,而修改用户的接口中则校验了id不能为空。

常用校验注解

以上就是楼主在项目中使用validation的总结归纳,下面收集了一些常用注解,红色的标注则是楼主在项目中用的比较多的。

JSR提供的校验注解:
@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(regex) 被注释的元素必须符合指定的正则表达式

Hibernate Validator提供的校验注解:
@NotBlank() 验证字符串非null且非空格,长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

参考博文: https://www.jb51.net/article/157604.htm

到此这篇关于Spring-Validation 后端数据校验的实现的文章就介绍到这了,更多相关Spring Validation数据校验内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 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

  • 详解使用spring validation完成数据后端校验

    前言 数据的校验是交互式网站一个不可或缺的功能,前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验.但是为了避免用户绕过浏览器,使用http工具直接向后端请求一些违法数据,服务端的数据校验也是必要的,可以防止脏数据落到数据库中,如果数据库中出现一个非法的邮箱格式,也会让运维人员头疼不已.我在之前保险产品研发过程中,系统对数据校验要求比较严格且追求可变性及效率,曾使用drools作为规则引擎,兼任了校验的功能.而在一般的应用,可以使用本文将要介绍的vali

  • SpringMVC实现Validation校验过程详解

    这篇文章主要介绍了SpringMVC实现Validation校验过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.概述 对前端的校验大多数通过js在页面校验,这种方法比较简单,如果对安全性考虑,还要在后台校验. springmvc使用JSR-303(javaEE6规范的一部分)校验规范,springmvc使用的是Hibernate Validator(和Hibernate的ORM) 二.步骤 2.1 引入 Hibernate Vali

  • springboot使用校验框架validation校验的示例

    b/s系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的. Spring3支持JSR-303验证框架,JSR-303 是Java EE 6 中的一项子规范,叫做BeanValidation,官方参考实现是hibernate Validator(与Hibernate ORM 没有关系),JSR 303 用于对Java Bean 中的字段的值进行验证. Validator主要是校验用户提交的数据的合理性的,比如是否为

  • Spring自带的校验框架Validation的使用实例

    1.首先来一个项目结构图以及所需jar包 可以看到,没有添加除了日志和jstl相关的jar包外,没有其他spring以外的第三方jar包(即使用的是spring自带的校验框架). 2.从前台页面开始,首先是接收用户信息的表单loginForm.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@

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

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

  • Spring Validation实现数据校验的示例

    目录 一.什么是 Spring Validation 二.实现数据校验 准备相关jar包 Validator接口方式 基于注解方式(Bean Validation) 基于方法的方式 自定义校验 一.什么是 Spring Validation 在开发中,我们经常遇到参数校验的需求,比如用户注册的时候,要校验用户名不能为空.用户名长度不超过20个字符.手机号是合法的手机号格式等等.如果使用普通方式,我们会把校验的代码和真正的业务处理逻辑耦合在一起,而且如果未来要新增一种校验逻辑也需要在修改多个地方.

  • Spring-Validation 后端数据校验的实现

    前言 最近看到很多童鞋在项目中的对请求参数的校验都用的if来判断各参数的属性,如: if(StringUtils.isBlank(username)){ return RR.exception("账号不能为空"); } if(StringUtils.isBlank(password)){ return RR.exception("密码不能为空"); } if(StringUtils.isBlank(realName)){ return RR.exception(&q

  • spring validation多层对象校验教程

    目录 spring validation多层对象校验 1.第一层对象定义 2.第二层对象 3.Controller层校验使用 validation校验对象多个字段返回的消息内容顺序随机问题 问题描述 解决办法 spring validation多层对象校验 1.第一层对象定义 import java.io.Serializable; import javax.validation.Valid; /** * 请求参数 * @Title: ReqIn.java * @Package com.spri

  • SpringBoot后端数据校验实战操作指南

    目录 1.为什么后端要进行数据校验? 2.怎么使用数据校验?(要添加对应依赖) (1)在实体上的属性上添加校验注解: (2)在controller层的方法前加上注解@Validated开启数据校验 (3)如果每个方法要校验的参数不同,可以使用分组校验. 实现对手机号码的数据校验: 1.自定义注解: 2.定义号码的校验类 3.自定义校验规则 4.捕获数据校验抛出的异常: 入参对象包含集合时,怎么对集合中的每个属性进行校验 总结 1.为什么后端要进行数据校验? 如果新增一个数据,直接在前端页面新增,

  • 如何使用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

  • Spring mvc服务端数据校验实现流程详解

    B/S 系统中对http 请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的,实际上,几乎所有的系统,凡是涉及到数据校验,都需要在服务端进行二次校验.为什么要在服务端进行二次校验呢?这需要理解客户端校验和服务端校验各自的目的. 客户端校验,我们主要是为了提高用户体验,例如用户输入一个邮箱地址,要校验这个邮箱地址是否合法,没有必要发送到服务端进行校验,直接在前端用 js 进行校验即可.但是大家需要明白的是,前端校验无法代替后端校验

  • SpringBoot后端进行数据校验JSR303的使用详解

    如果只想查看注解,请跳到文章末尾部分 简介 在前后端进行数据交互中,在前端把数据传送到后端前,一般会先进行校验一次,校验成功之后,才把数据发送到后端.但是我们在服务端还得在对数据进行一次校验.因为请求数据发送的链接很容易获取,可以不经过前端界面,使用postman等工具直接向后台发送数据,这就可能造成发送的数据是不合法的情况. 项目创建 首先创建一个springboot项目 使用的springboot版本为:(本文代码以该版本为准,不同版本springboot,在下面内容会出现一些差异) <pa

  • Spring boot通过切面,实现超灵活的注解式数据校验过程

    目录 通过切面,实现超灵活的注解式数据校验 Spring MVC的校验方式 通过切面实现自己的注解式数据校验 Spring boot aop注解数据权限校验 注解类 AOP切面 使用 通过切面,实现超灵活的注解式数据校验 在企业系统的开发中,用户表单输入的场景是会经常遇见的,如何让数据校验脱离于业务代码逻辑,谁也不想在逻辑代码里对字段逐一判断.... Spring MVC的校验方式 在使用Spring MVC时的时候,直接使用hibernate-validator的注解,如下: public c

  • Spring Boot 通过注解实现数据校验的方法

    一.依赖 <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> &l

随机推荐