热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SpringBoot配合HibernateValidator参数校验

SpringBoot中结合HibernateValidator可以实现优雅的参数校验,而不必在业务代码中写一大堆的参数校验逻辑。HibernateValidator的基本使用可以参

Spring Boot中结合Hibernate Validator可以实现优雅的参数校验,而不必在业务代码中写一大堆的参数校验逻辑。Hibernate Validator的基本使用可以参考Spring表单校验,这里介绍一种结合全局异常捕获的方式来实现低耦合简洁的参数校验解决方案。

 

方法参数校验

新建一个Spring Boot工程,版本为2.1.0.RELEASE,artifactIdvalidator,并引入spring-boot-starter-webcommons-lang3依赖:

 
 
      org.springframework.boot
      spring-boot-starter-web
 


 
      org.apache.commons
      commons-lang3
 

 

项目结构如下所示:

Spring Boot配合Hibernate Validator参数校验

spring-boot-starter-web已经包含了hibernate-validator,所以无需单独引入:Spring Boot配合Hibernate Validator参数校验

com.example.demo下新建controller包,然后创建TestController,定义一个test1方法:

@RestController
@Validated
public class TestController {

  @GetMapping("test1")
  public String test1(
          @NotBlank(message = "{required}") String name,
          @Email(message = "{invalid}") String email) {
      return "success";
  }
}

 

test1方法的name参数使用@NotBlank标注,表示不能为空,提示信息为{required}占位符里的内容;email参数使用@Email注解标注,表示必须为一个合法的邮箱值(可以为空),提示信息为{invalid}占位符里的内容。要让参数校验生效,我们还需在类上使用@Validated注解标注。

接下来定义上面两个占位符的内容。在resources目录下新建ValidationMessages.properties文件,内容如下:

required=\u4e0d\u80fd\u4e3a\u7a7a
invalid=\u683c\u5f0f\u4e0d\u5408\u6cd5

 

内容为中文转Unicode后的值,可以使用http://tool.chinaz.com/tools/unicode.aspx网站转换,\u4e0d\u80fd\u4e3a\u7a7a转为中文为“不能为空”,\u683c\u5f0f\u4e0d\u5408\u6cd5转为中文为“格式不合法”。

启动项目,使用Postman进行测试,参数内容如下所示:

Spring Boot配合Hibernate Validator参数校验

这里name参数值为空,email参数值为123,访问后,控制台输出异常如下:

Spring Boot配合Hibernate Validator参数校验

可见,使用这种方式参数校验不通过时,会抛出javax.validation.ConstraintViolationException,我们使用全局异常捕获来处理这种异常:

com.example.demo下新建handler包,然后创建GlobalExceptionHandler

@RestControllerAdvice
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class GlobalExceptionHandler {

  /**
    * 统一处理请求参数校验(普通传参)
    *
    * @param e ConstraintViolationException
    * @return FebsResponse
    */
  @ExceptionHandler(value = ConstraintViolationException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  public String handleConstraintViolationException(ConstraintViolationException e) {
      StringBuilder message = new StringBuilder();
      Set> violatiOns= e.getConstraintViolations();
      for (ConstraintViolation violation : violations) {
          Path path = violation.getPropertyPath();
          String[] pathArr = StringUtils.splitByWholeSeparatorPreserveAllTokens(path.toString(), ".");
          message.append(pathArr[1]).append(violation.getMessage()).append(",");
      }
      message = new StringBuilder(message.substring(0, message.length() - 1));
      return message.toString();
  }
}

 

上面主要的逻辑是获取校验不通过的参数名称,然后拼接上提示信息,并且HTTP返回状态码为400。重启项目,再次访问刚刚的链接,响应如下所示:

Spring Boot配合Hibernate Validator参数校验

使用实体传参

当参数较少的时候可以使用上面这种方式,但如果参数众多上面的方式就略显繁琐了。这时候我们可以使用实体对象来进行传参。

为了模拟这种情况,我们在com.example.demo路径下新建domain包,然后新建User类:

public class User implements Serializable {
  private static final long serialVersiOnUID= -2731598327208972274L;

  @NotBlank(message = "{required}")
  private String name;

  @Email(message = "{invalid}")
  private String email;

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }

  public String getEmail() {
      return email;
  }

  public void setEmail(String email) {
      this.email = email;
  }
}

 

接着在TestController里创建一个test2方法:

@GetMapping("test2")
public String test2(@Valid User user) {
  return "success";
}

 

使用实体对象传参的方式参数校验需要在相应的参数前加上@Valid注解。重启项目,再次访问下面这个请求:Spring Boot配合Hibernate Validator参数校验

控制台会输出如下信息:

Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'user' on field 'name': rejected value []; codes [NotBlank.user.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.name,name]; arguments []; default message [name]]; default message [不能为空]
Field error in object 'user' on field 'email': rejected value [123]; codes [Email.user.email,Email.email,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.email,email]; arguments []; default message [email],[Ljavax.validation.constraints.Pattern$Flag;@5fb82092,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@cc0c307]; default message [格式不合法]]

这时候我们需要在GlobalExceptionHandler捕获org.springframework.validation.BindException异常:

/**
* 统一处理请求参数校验(实体对象传参)
*
* @param e BindException
* @return FebsResponse
*/
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String validExceptionHandler(BindException e) {
  StringBuilder message = new StringBuilder();
  List fieldErrors = e.getBindingResult().getFieldErrors();
  for (FieldError error : fieldErrors) {
      message.append(error.getField()).append(error.getDefaultMessage()).append(",");
  }
  message = new StringBuilder(message.substring(0, message.length() - 1));
  return message.toString();

}

 

重启项目,再次访问刚刚的请求,响应如下所示:

Spring Boot配合Hibernate Validator参数校验

我们将请求参数改为合法的内容:

Spring Boot配合Hibernate Validator参数校验

点击访问,响应如下所示:

Spring Boot配合Hibernate Validator参数校验


推荐阅读
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 解决java.lang.IllegalStateException: ApplicationEventMulticaster not initialized错误的方法和原因
    本文介绍了解决java.lang.IllegalStateException: ApplicationEventMulticaster not initialized错误的方法和原因。其中包括修改包名、解决service name重复、处理jar包冲突和添加maven依赖等解决方案。同时推荐了一个人工智能学习网站,该网站内容通俗易懂,风趣幽默,值得一看。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 本文介绍了在满足特定条件时如何在输入字段中使用默认值的方法和相应的代码。当输入字段填充100或更多的金额时,使用50作为默认值;当输入字段填充有-20或更多(负数)时,使用-10作为默认值。文章还提供了相关的JavaScript和Jquery代码,用于动态地根据条件使用默认值。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • SpringBoot简单日志配置
     在生产环境中,只打印error级别的错误,在测试环境中,可以调成debugapplication.properties文件##默认使用logbacklogging.level.r ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了多因子选股模型在实际中的构建步骤,包括风险源分析、因子筛选和体系构建,并进行了模拟实证回测。在风险源分析中,从宏观、行业、公司和特殊因素四个角度分析了影响资产价格的因素。具体包括宏观经济运行和宏经济政策对证券市场的影响,以及行业类型、行业生命周期和行业政策对股票价格的影响。 ... [详细]
  • 加密世界下一个主流叙事领域:L2、跨链桥、GameFi等
    本文介绍了加密世界下一个主流叙事的七个潜力领域,包括L2、跨链桥、GameFi等。L2作为以太坊的二层解决方案,在过去一年取得了巨大成功,跨链桥和互操作性是多链Web3中最重要的因素。去中心化的数据存储领域也具有巨大潜力,未来云存储市场有望达到1500亿美元。DAO和社交代币将成为购买和控制现实世界资产的重要方式,而GameFi作为数字资产在高收入游戏中的应用有望推动数字资产走向主流。衍生品市场也在不断发展壮大。 ... [详细]
author-avatar
HE-KILL-MY-EGO
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有