SpringBoot + validation 接口参数校验的思路详解

 更新时间:2020年10月22日 10:51:08   作者:乾源  
这篇文章主要介绍了SpringBoot + validation 接口参数校验,本文通过项目实践+场景分析给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

        有参数传递的地方都少不了参数校验。在web开发中,前端的参数校验是为了用户体验,后端的参数校验是为了安全。试想一下,如果在controller层中没有经过任何校验的参数通过service层、dao层一路来到了数据库就可能导致严重的后果,最好的结果是查不出数据,严重一点就是报错,如果这些没有被校验的参数中包含了恶意代码,那就可能导致更严重的后果。

实践

一、引入依赖

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

二、使用校验

在controller层的参数校验可以分为两种场景:

单个参数校验
实体类参数校验

2.1 单参数校验

/**
 * 参数校验测试 控制类
 * @author oyc
 */
@RestController
@RequestMapping("user")
@Validated
public class RequestParamsValidatedController {
 
 private Logger logger = LoggerFactory.getLogger(this.getClass());
 
 @GetMapping
 public User test(@NotNull(message = "姓名不能为空") String name,
      @NotNull(message = "年龄不能为空") @Max(value = 99, message = "不能大于200岁") Integer age) {
  logger.info("name:" + name + " -age:" + age);
  return new User(name, age);
 }
}

2.2 实体类参数校验

/**
 * 参数校验测试 控制类
 * @author oyc
 */
@RestController
@RequestMapping("user")
@Validated
public class RequestParamsValidatedController {
 
 private Logger logger = LoggerFactory.getLogger(this.getClass());
 
 @PostMapping
 public User save(@Validated User user) {
  logger.info(user.toString());
  return user;
 }
}
package com.oycbest.springbootvalidated.vo;
 
 
import javax.validation.constraints.*;
import java.io.Serializable;
 
/**
 * 用户实体类
 * @author oyc
 */
public class User implements Serializable {
 private String userId;
 
 @NotNull(message = "用户名不能为空")
 private String userName;
 
 @NotNull(message = "年龄不能为空")
 @Max(value = 100, message = "年龄不能大于100岁")
 private int age;
 
 @NotNull(message = "邮箱不能为空")
 @Email(message = "邮箱格式不正确")
 private String email;
 
 @NotNull(message = "电话号码不能为空")
 private String phoneNumber;
 
 public User(@NotNull(message = "用户名不能为空") String userName, int age) {
  this.userName = userName;
  this.age = age;
 }
 
 public User() {
 }
 
 public User(String userId, @NotNull(message = "用户名不能为空") String userName, int age, String email, String phoneNumber) {
  this.userId = userId;
  this.userName = userName;
  this.age = age;
  this.email = email;
  this.phoneNumber = phoneNumber;
 }
 
 public String getUserId() {
  return userId;
 }
 
 public void setUserId(String userId) {
  this.userId = userId;
 }
 
 public String getUserName() {
  return userName;
 }
 
 public void setUserName(String userName) {
  this.userName = userName;
 }
 
 public int getAge() {
  return age;
 }
 
 public void setAge(int age) {
  this.age = age;
 }
 
 public String getEmail() {
  return email;
 }
 
 public void setEmail(String email) {
  this.email = email;
 }
 
 public String getPhoneNumber() {
  return phoneNumber;
 }
 
 public void setPhoneNumber(String phoneNumber) {
  this.phoneNumber = phoneNumber;
 }
 
 @Override
 public String toString() {
  return "User{" +
    "userId='" + userId + '\'' +
    ", userName='" + userName + '\'' +
    ", age=" + age +
    ", email='" + email + '\'' +
    ", phoneNumber='" + phoneNumber + '\'' +
    '}';
 }
}

2.3 定义统一异常处理

package com.oycbest.springbootvalidated.exception;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
 
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.List;
import java.util.Set;
 
/**
 * 全局异常处理
 *
 * @author oyc
 */
@ControllerAdvice
@Component
public class GlobalExceptionHandler {
 private Logger logger = LoggerFactory.getLogger(this.getClass());
 
 @Bean
 public MethodValidationPostProcessor methodValidationPostProcessor() {
  return new MethodValidationPostProcessor();
 }
 
 @ExceptionHandler
 @ResponseBody
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 public String handle(ValidationException exception) {
  logger.error("请求异常:" + exception.getMessage());
  if (exception instanceof ConstraintViolationException) {
   ConstraintViolationException exs = (ConstraintViolationException) exception;
 
   Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
   for (ConstraintViolation<?> item : violations) {
    //打印验证不通过的信息
    logger.error("请求异常:" + item.getMessage());
   }
  }
  return "请求异常: " + exception.getMessage();
 }
 
 @ResponseBody
 @ExceptionHandler(value = BindException.class)
 public String bindException(Exception e) {
  if (e instanceof BindException) {
   BindException exs = (BindException) e;
   List<FieldError> fieldErrors = exs.getFieldErrors();
   for (FieldError item : fieldErrors) {
    logger.error("请求异常:" + item.getDefaultMessage());
   }
  }
  logger.error("数据绑定异常:" + e.getMessage());
  return "数据绑定异常";
 }
 
 @ResponseBody
 @ExceptionHandler(value = Exception.class)
 public String defaultException(Exception e) {
  logger.error("请求异常:" + e.getMessage());
  return "请求异常 " + e.getMessage();
 }
 
}

三、约束性注解(简单)说明

注解

功能

@AssertFalse

可以为null,如果不为null的话必须为false

@AssertTrue

可以为null,如果不为null的话必须为true

@DecimalMax

设置不能超过最大值

@DecimalMin

设置不能超过最小值

@Digits

设置必须是数字且数字整数的位数和小数的位数必须在指定范围内

@Future

日期必须在当前日期的未来

@Past

日期必须在当前日期的过去

@Max

最大不得超过此最大值

@Min

最大不得小于此最小值

@NotNull

不能为null,可以是空

@Null

必须为null

@Pattern

必须满足指定的正则表达式

@Size

集合、数组、map等的size()值必须在指定范围内

@Email

必须是email格式

@Length

长度必须在指定范围内

@NotBlank

字符串不能为null,字符串trim()后也不能等于“”

@NotEmpty

不能为null,集合、数组、map等size()不能为0;字符串trim()后可以等于“”

@Range

值必须在指定范围内

@URL

必须是一个URL

到此这篇关于SpringBoot + validation 接口参数校验的文章就介绍到这了,更多相关SpringBoot + validation 接口参数校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java 反射机制详解及实例代码

    java 反射机制详解及实例代码

    这篇文章主要介绍了java 反射机制详解及实例代码的相关资料,需要的朋友可以参考下
    2016-11-11
  • Java实现List去重的几种方法总结

    Java实现List去重的几种方法总结

    这篇文章主要为大家详细介绍了Java中List去重的几种常用方法总结,文中的示例代码讲解详细,具有一定的学习和参考价值,需要的小伙伴可以了解一下
    2023-09-09
  • 如何用java给一个文件夹打成压缩包(附代码)

    如何用java给一个文件夹打成压缩包(附代码)

    项目中需要将文件夹打包成压缩包下载,所以下面这篇文章主要给大家介绍了关于如何用java给一个文件夹打成压缩包的相关资料,文中给出了详细的代码示例,需要的朋友可以参考下
    2023-10-10
  • 使用logback实现按自己的需求打印日志到自定义的文件里

    使用logback实现按自己的需求打印日志到自定义的文件里

    这篇文章主要介绍了使用logback实现按自己的需求打印日志到自定义的文件里,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 基于java+springboot+mybatis+laiyu实现学科竞赛管理系统

    基于java+springboot+mybatis+laiyu实现学科竞赛管理系统

    这篇文章主要介绍了基于java+springboot+mybatis+laiyu实现的学科竞赛管理系统,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Spring Boot 4.0对于Java开发的影响和前景

    Spring Boot 4.0对于Java开发的影响和前景

    探索Spring Boot 4.0如何彻底革新Java开发,提升效率并开拓未来可能性!别错过这篇紧凑的指南,它带你领略Spring Boot的强大魅力和潜力,准备好了吗?
    2024-02-02
  • IDEA 工程里 new不出来Vue文件的图文解决方案

    IDEA 工程里 new不出来Vue文件的图文解决方案

    这篇文章主要介绍了IDEA 工程里 new不出来Vue文件的解决方案,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • Java基于深度优先遍历的随机迷宫生成算法

    Java基于深度优先遍历的随机迷宫生成算法

    今天小编就为大家分享一篇关于Java基于深度优先遍历的随机迷宫生成算法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • maven中no main manifest attribute的问题解决

    maven中no main manifest attribute的问题解决

    本文主要介绍了maven中no main manifest attribute的问题解决,这个错误通常意味着Spring Boot应用在启动时遇到了问题,下面就来具体介绍一下,感兴趣的可以了解一下
    2024-08-08
  • Java CountDownLatch的源码硬核解析

    Java CountDownLatch的源码硬核解析

    对于并发执行,Java中的CountDownLatch是一个重要的类。为了更好的理解CountDownLatch这个类,本文将通过例子和源码带领大家深入解析这个类的原理,感兴趣的可以学习一下
    2022-10-10

最新评论