https://www.jianshu.com/p/89a675b7c900

在日常开发写rest接口时,接口参数校验这一部分是必须的,但是如果全部用代码去做,显得十分麻烦,spring也提供了这部分功能,本文来探究一下如何实现

1.配置

spring-boot-starter-web包自动依赖hibernate-validator,不用再重复引入,直接开搞

<dependency><groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.3.1.Final</version> </dependency> 

声明一个bean注册到spring容器,这个bean是一个容器后处理器,会把校验的逻辑通过AOP织入有@Validated注解的class,具体可以看这个类的源码

这一步在springboot其实也不用做,ValidationAutoConfiguration这个配置类自动帮我们做了

 @Beanpublic MethodValidationPostProcessor methodValidationPostProcessor(){ return new MethodValidationPostProcessor(); } 

验证不通过会产生异常,因为我们项目提供rest接口,所以通过全局捕获异常,然后转换为json给前台


@ControllerAdvice
public class GlobalExceptionHandler { /** * 用来处理bean validation异常 * @param ex * @return */ @ExceptionHandler(ConstraintViolationException.class) @ResponseBody public WebResult resolveConstraintViolationException(ConstraintViolationException ex){ WebResult errorWebResult = new WebResult(WebResult.FAILED); Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations(); if(!CollectionUtils.isEmpty(constraintViolations)){ StringBuilder msgBuilder = new StringBuilder(); for(ConstraintViolation constraintViolation :constraintViolations){ msgBuilder.append(constraintViolation.getMessage()).append(","); } String errorMessage = msgBuilder.toString(); if(errorMessage.length()>1){ errorMessage = errorMessage.substring(0,errorMessage.length()-1); } errorWebResult.setInfo(errorMessage); return errorWebResult; } errorWebResult.setInfo(ex.getMessage()); return errorWebResult; } @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody public WebResult resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex){ WebResult errorWebResult = new WebResult(WebResult.FAILED); List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors(); if(!CollectionUtils.isEmpty(objectErrors)) { StringBuilder msgBuilder = new StringBuilder(); for (ObjectError objectError : objectErrors) { msgBuilder.append(objectError.getDefaultMessage()).append(","); } String errorMessage = msgBuilder.toString(); if (errorMessage.length() > 1) { errorMessage = errorMessage.substring(0, errorMessage.length() - 1); } errorWebResult.setInfo(errorMessage); return errorWebResult; } errorWebResult.setInfo(ex.getMessage()); return errorWebResult; } } 

这两个异常分别对应校验的两种使用方式

  1. 在方法里面校验
  2. 在bean对象里面校验
    经过测试,以上两种形式的数据验证不仅仅对controller层有用,在service层也行,只要这个类在spring ioc容器里面

2.使用

2.1常用校验注解

@AssertFalse 校验false
@AssertTrue 校验true @DecimalMax(value=,inclusive=) 小于等于value, inclusive=true,是小于等于 @DecimalMin(value=,inclusive=) 与上类似 @Max(value=) 小于等于value @Min(value=) 大于等于value @NotNull 检查Null @Past 检查日期 @Pattern(regex=,flag=) 正则 @Size(min=, max=) 字符串,集合,map限制大小 @Valid 对po实体类进行校验 

这篇文章介绍的注解更全一点

2.2在方法参数上使用

@Controller
@Validated
public class ValidationController {@GetMapping("/validate1") @ResponseBody public String validate1( @Size(min = 1,max = 10,message = "姓名长度必须为1到10")@RequestParam("name") String name, @Min(value = 10,message = "年龄最小为10")@Max(value = 100,message = "年龄最大为100") @RequestParam("age") Integer age, @Future @RequestParam("birth")@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") Date birth){ return "validate1"; } } 

注意类名需要加注解@Validated
校验失败会抛出ConstraintViolationException异常
然后我们在全局异常捕获类捕获这个异常,返回给前台对应的错误json

2.3在bean内属性上使用

给model类增加校验注解

public class User { @Size(min = 1,max = 10,message = "姓名长度必须为1到10") private String name; @NotEmpty private String firstName; @Min(value = 10,message = "年龄最小为10")@Max(value = 100,message = "年龄最大为100") private Integer age; @Future @JSONField(format="yyyy-MM-dd HH:mm:ss") private Date birth; ...getter setter } 

在controller对应User实体前增加@Valid注解

@PostMapping("/validate2")
@ResponseBody
public User validate2(@Valid @RequestBody User user){ return user; } 

3.扩展

除了默认提供的校验注解外,我们可以定义自己的校验注解

3.1.创建约束注解类

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) @Documented @Constraint(validatedBy = { HandsomeBoyValidator.class}) public @interface HandsomeBoy { String message() default "盛超杰最帅"; String name(); Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default {}; } 

注意:message用于显示错误信息这个字段是必须的,groups和payload也是必须的
@Constraint(validatedBy = { HandsomeBoyValidator.class})用来指定处理这个注解逻辑的类

一开始写了这个自定义注解和验证类,发现没有生效,最后发现是@Constraint这个注解里的类没有配置,还跟了很多源码,蛋疼,总的来讲,这个配置还是挺方便的

外国人写的一篇博客,介绍自定义验证配置,挺全的

3.2.创建验证器类

public class HandsomeBoyValidator implements ConstraintValidator<HandsomeBoy, User> { private String name; /** * 用于初始化注解上的值到这个validator * @param constraintAnnotation */ @Override public void initialize(HandsomeBoy constraintAnnotation) { name =constraintAnnotation.name(); } /** * 具体的校验逻辑 * @param value * @param context * @return */ @Override public boolean isValid(User value, ConstraintValidatorContext context) { return name ==null || name.equals(value.getName()); } } 

这边的功能是user类里面的name字段必须和配置的一样,否则输出一个事实

3.3. 测试

@PostMapping("/validate3")
@ResponseBody
public User validate3(@Valid @HandsomeBoy(name = "scj",message = "盛超杰第二帅") @RequestBody  User user){return user; } 

如果验证不通过,会输出盛超杰第二帅,全局异常处理器不要忘记配置

4.demo源码下载

https://github.com/shengchaojie/springboot-validation-demo

小礼物走一走,来简书关注我

转载于:https://www.cnblogs.com/kelelipeng/p/10183904.html

springboot 参数校验详解相关推荐

  1. 补习系列(4)-springboot 参数校验详解

    目录 目标 一.PathVariable 校验 二.方法参数校验 三.表单对象校验 四.RequestBody 校验 五.自定义校验规则 六.异常拦截器 参考文档 目标 对于几种常见的入参方式,了解如 ...

  2. SpringBoot的配置详解application

    SpringBoot的配置文件application有两种文件格式,两种配置的内容是一致的,只是格式不一致. 1.application.properties 2.application.yml或者a ...

  3. creo配置文件config选项详解_5年资深架构师重点聚焦:SpringBoot的配置详解+内嵌Servlet容器

    Spring Boot的配置详解 在本节中,我们将重点聚焦在Spring Boot的配置方面. 理解Spring Boot的自动配置 按照"约定大于配置"的原则,Spring Bo ...

  4. SpringBoot yaml语法详解

    SpringBoot yaml语法详解 1.yaml基本语法 2.yaml给属性赋值 3.JSR303校验 4.SpringBoot的多环境配置 1.yaml基本语法 通常情况下,Spring Boo ...

  5. JVM调优系列--Java命令选项(参数)--大全/详解/常用

    原文网址:JVM调优系列--Java命令选项(参数)--大全/详解/常用_IT利刃出鞘的博客-CSDN博客 简介 说明        本文介绍Java的java命令用法,包括:常用用法.选项大全. J ...

  6. Linux rpm 命令参数使用详解

    Linux rpm 命令参数使用详解 RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的"添加/删除程序" rpm 执行安装 ...

  7. Springboot传参详解

    作者简介 作者名:编程界明世隐 简介:CSDN博客专家,从事软件开发多年,精通Java.JavaScript,博主也是从零开始一步步把学习成长.深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢 ...

  8. SpringBoot 整合EasyExcel详解(一)-高性能Excel方案

    SpringBoot 整合EasyExcel详解(二)-写Excel SpringBoot 整合EasyExcel详解(三)-填充Excel-官方原版 一.概述 Java解析.生成Excel比较有名的 ...

  9. Python必备基本技能——命令行参数args详解

    Python必备基本技能--命令行参数args详解 1. 效果图 2. 源码 2.1 简单命令行参数 2.1 轮廓检测源代码 参考 这篇博客将介绍一项开发人员.工程师和计算机科学家必备的技能--命令行 ...

最新文章

  1. Java Reflection(十):数组
  2. 苹果M1芯片升级果然很炸场:性能暴涨功耗速降!但最香新品竟是无降噪AirPods 3...
  3. [翻译] VLDContextSheet
  4. html 日历系统 源码,calendar.html
  5. C#反射与特性(一):反射基础
  6. docker 打包mysql_基于docker部署mysql的数据持久化问题
  7. java 盘符 系统_001-Java再回首开篇-入门基础
  8. 看这玩意复习你还会挂科?《软件工程篇》
  9. 递归多线程实现前缀和
  10. opp原则_OPP--面向对象知识点
  11. python subprocess pipe_python类库31[进程subprocess与管道pipe]
  12. linux基础总结1
  13. flink cdc 2.0.0 sql 开发模板,及踩坑记录
  14. PySide2嵌入外部程序
  15. Win10+Ubuntu双系统修复Ubuntu系统引导
  16. 把oblog3.13转换成PHP
  17. HDU 6438-Buy and Resell
  18. 制作Mac版的星际争霸II(StarCraft II)
  19. Unity 3D 图形学 Shader之顶点与片段着色器(五)
  20. Word处理控件Aspose.Words功能演示:用Java从Word文档中提取文本

热门文章

  1. 天河二号超级计算机拿来玩游戏,“天河二号超级计算机”是我国独立自主研制的超级计算机系统,...
  2. oracle 表空间写文件,Oracle表空间和数据文件管理
  3. 对应生成树的基本回路_7.1 图的定义与基本术语
  4. 查oracle事务超时时间,ORA-24756: 事务处理不存在 分析
  5. java线程三种方法,Java基础_线程的使用及创建线程的三种方法
  6. java开发模型_java开发模型MVC
  7. python切换ip群发邮件_python获取外网IP并发邮件的实现方法
  8. CF思维联系–CodeForces - 222 C Reducing Fractions(数学+有技巧的枚举)
  9. 贷款不还会有什么后果?
  10. 北京国际图书博览会暨2007 BIBF