1、引入pom依赖

<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.20.Final</version>
</dependency>

2、实体类

单层校验

直接在类属性上使用注解

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern; public class ClassInfoVo {
@Pattern(regexp = "^.{0,100}$", message = "班级id最长为100个字符")
private String classId; @Pattern(regexp = "^.{0,100}$", message = "班级名最长为100个字符")
@NotNull(message = "缺少必要的参数规则name")
@NotBlank(message = "班级名不能为null,或者只包含空格")
@NotEmpty(message = "班级name不能为null或者长度为0")
private String className;
}
嵌套多层

在对象属性上使用@Valid注解

import javax.validation.Valid;
import java.util.List; public class SchoolInfo {
private String schoolName;
private String schoolId; @Valid
private List<ClassInfoVo> rules;
} public class ClassInfoVo {
@Pattern(regexp = "^.{0,100}$", message = "班级id最长为100个字符")
private String classId; @Pattern(regexp = "^.{0,100}$", message = "班级名最长为100个字符")
@NotNull(message = "缺少必要的参数规则name")
@NotBlank(message = "班级名不能为null,或者只包含空格")
@NotEmpty(message = "班级name不能为null或者长度为0")
private String className;
}

3、控制层

使用@Valid注解

@RestController
@RequestMapping(value = "/school")
public class Controller {
@Autowired
private SchoolService schoolService; @PostMapping(value = "/query")
public BaseResponse query(@RequestBody @Valid SchoolInfo infoVo) {
return schoolService.query(infoVo);
}
}

4、全局异常处理

  • 处理Get请求,抛出BindException异常
  • 处理请求参数格式错误 @RequestParam上,抛出ConstraintViolationException异常
  • 处理请求参数格式错误 @RequestBody上,抛出MethodArgumentNotValidException
@ControllerAdvice
public class YourProjectNameExceptionAdvice {
private static final Logger LOGGER = LoggerFactory.getLogger(YourProjectNameExceptionAdvice.class); /**
* 校验错误拦截处理
* 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
*
* @param exception 错误信息集合
* @return 错误信息
*/
@ResponseBody
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse bindExceptionHandler(BindException exception) {
LOGGER.error("BindException encountered: {0}", exception);
String message =
exception.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining());
return BaseResponse.newError("YourProjectName_BindException", message);
} /**
* 校验错误拦截处理
* 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
*
* @param exception 错误信息集合
* @return 错误信息
*/
@ResponseBody
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse constraintViolationHandler(ConstraintViolationException exception) {
LOGGER.error("ConstraintViolation exception encountered: {0}", exception);
return BaseResponse.newError("YourProjectName_ConstraintViolation", exception.getMessage());
} /**
* 校验错误拦截处理
* 处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
*
* @param exception 错误信息集合
* @return 错误信息
*/
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResponse methodArgumentNotValidHandler(MethodArgumentNotValidException exception) {
LOGGER.error("MethodArgumentNotValid exception encountered: {0}", exception);
BindingResult bindingResult = exception.getBindingResult();
StringBuilder sb = new StringBuilder();
for (FieldError fieldError : bindingResult.getFieldErrors()) {
sb.append(fieldError.getField()).append(": ").append(fieldError.getDefaultMessage()).append(", ");
}
return BaseResponse.newError("YourProjectName_MethodArgumentNotValid", sb.toString());
}
}

5、如果多个请求参数校验失败,则遇到一个校验失败就抛出异常,接下来的异常参数不做校验。

@Configuration
public class WebConfig {
@Bean
public Validator validator() {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
//failFast的意思只要出现校验失败的情况,就立即结束校验,不再进行后续的校验。
.failFast(true)
.buildValidatorFactory(); return validatorFactory.getValidator();
} @Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator());
return methodValidationPostProcessor;
}
}

6、校验时常用注解

JSR303定义的校验类型

Constraint
详细信息
@Valid 递归的对关联对象进行校验,如果关联对象是个集合或者数组,那么对其中的元素进行递归校验
@Pattern(value) 符合指定的正则表达式(校验非法字符)
@NotNull 参数不为 null
@NotEmpty 参数不能为null,或者是空
@NotBlank() 参数不能为null,或者被Trim的长度是否大于0(可以用来校验全为空格字符)
@Min() 一个数字,值大于给定值
@Max() 一个数字,值小于给定值
@Digits (integer, fraction) 一个数字,其值必须在可接受的范围内

举例代码中使用的比较代表的:

@Pattern(regexp = "^[\\u4E00-\\u9FA5\\w\\-]{1,57}$", message = "只能包含中文字符、英文字符、数字、下划线和中横线,1~57个字符")

@Pattern(regexp = "^((?!=|\\+|-|@|>|<|%).)((?!>|<|%).){0,127}$", message = "不能以=,+,-或@开头,不能包含<,>和%字符,最长为128个字符")

@Pattern(regexp = "^(?:false|true)$", message = "只支持false/true")

@Pattern(regexp = "^[A-Za-z0-9]{32}$", message = "只能是32位的uuid(只有英文和字母)")

@Pattern(regexp = "^[\\w-.;]{1,100}$", message = "最长为100,只能包含英文、数字、“-”、“_”、“;”")

@Pattern(
regexp = "^[/][/\\w-.]{1,254}$",
message = "须以“/”开头,只能包含字母、数字、“/”、“_”、“-”和“.”," + "长度不少于2位,长度最长为255") @Pattern(regexp = "^(?:A|B)$", message = "类型必须为A或者B") @Max(value = 2_140_000_000, message = "只能大于0小于2140000")
@Min(value = 0, message = "只能大于0小于2140000") @Max(value = 5000, message = "分页大小在【1,5000】之间")
@Min(value = 1, message = "分页大小在【1,5000】之间") @Digits(integer = 1, fraction = 0, message = "只能为0或1")
@Max(value = 1, message = "只能为0或1")
@Min(value = 0, message = "只能为0或1") @NotEmpty(message = "缺少必要的参数,数组classIds不能为null,或者长度为0")
private List<
@Pattern(regexp = "^[a-zA-Z\\d]{32}$", message = "id仅由字母和数字组成,且长度为32个字符")
@NotEmpty(message = "id不能为null或者为空") String>
classIds;

这些只是包含一些基本的校验,负责校验可以使用是定义校验注解的方式,主要是要实现ConstraintValidator的处理类。(不多介绍)

7、自定义注解

自定义注解名称

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ParamValidator.class)
public @interface RetryTimes {
String message() default "重试次数只能为0,5,10,20,50,100"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {};
}

同时实现ConstraintValidator类

public class ParamValidator implements ConstraintValidator<RetryTimes, Short> {
private static final Pattern PATTERN = Pattern.compile("^(?:0|5|10|20|50|100)$"); @Override
public boolean isValid(Short retryTimes, ConstraintValidatorContext constraintValidatorContext) {
return PATTERN.matcher(retryTimes.toString()).matches();
}
}

定义后,如何使用,直接在属性上添加该注解

@RetryTimes
private short retryTimes;

8、分组校验(后面补充)

SpringBoot系列(五) 接口校验(非空、非法字符/特殊字符、长度等)的更多相关文章

  1. springboot系列五、springboot常用注解使用说明

    一.controller相关注解 1.@Controller 控制器,处理http请求. 2.@RespController Spring4之后新加的注解,原来返回json需要@ResponseBod ...

  2. SpringBoot系列: CommandLineRunner接口的用处

    ========================================使用 CommandLineRunner 对Spring Bean进行额外初始化==================== ...

  3. SpringBoot系列五:SpringBoot错误处理(数据验证、处理错误页、全局异常)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念: SpringBoot 错误处理 2.具体内容 在之前的程序里面如果一旦出现了错误之后就会出现一堆的大白板,这个白板会 ...

  4. springboot系列五:springboot整合mybatisplus jsp

    一.用IDEA创建项目 1.添加pom.xml <?xml version="1.0" encoding="UTF-8"?> <project ...

  5. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  6. springboot项目中接口入参的简单校验

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  7. 【快学springboot】4.接口参数校验

    前言 在开发接口的时候,参数校验是必不可少的.参数的类型,长度等规则,在开发初期都应该由产品经理或者技术负责人等来约定.如果不对入参做校验,很有可能会因为一些不合法的参数而导致系统出现异常. 上一篇文 ...

  8. Springboot系列(七) 集成接口文档swagger,使用,测试

    Springboot 配置接口文档swagger 往期推荐 SpringBoot系列(一)idea新建Springboot项目 SpringBoot系列(二)入门知识 springBoot系列(三)配 ...

  9. Springboot:JSR303数据校验(五)

    @Validated //开启JSR303数据校验注解 校验规则如下: [一]空检查 @Null 验证对象是否为null @NotNull 验证对象是否不为null, 无法查检长度为0的字符串 @No ...

  10. SpringBoot系列(五)Mybatis整合完整详细版

    SpringBoot系列(五)Mybatis整合 目录 mybatis简介 项目创建 entity dao service serviceImpl mapper controller 1. Mybat ...

随机推荐

  1. 力扣445(java&python)-两数相加Ⅱ(中等)

    题目: 给你两个 非空 链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储一位数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示 ...

  2. EventBridge 特性介绍|以 IaC 的方式使用 EventBridge

    ​简介:本文将重点介绍 EventBridge 和 IaC 的重点概念和特性,然后演示如何应用 IaC 理念自动化部署 EventBridge 来使用这些概念和特性. 作者:王川(弗丁) 引言 Eve ...

  3. Alibaba Cloud Toolkit 中SLS插件助力线上服务问题排查

    ​简介:Alibaba Cloud Toolkit 是一款非常优秀的插件,新增SLS日志服务的功能,针对软件开发者日常工作中常见的问题排查场景,将日志服务平台的功能集成到ide当中,省去了不同窗口之间 ...

  4. 手把手教你如何构建 WPF 官方开源框架源代码

    从去年微软就将 WPF 开源了,差不多现在所有 WPF 的源代码都开源了.在学习框架的时候,我会做一些改动,期望能构建一个自己的版本进行测试.但是作为一个特别大的框架,想要构建跑起来可不是直接在 Vi ...

  5. git将本地项目关联远程仓库并上传到新分支

    混合项目开发,项目交接的时候没做好,新入职接手老项目的时候一脸懵逼,进入开发阶段时,越搞越不对,越搞越不对,总感觉 本地跑的项目和己方测试环境以及客户的测试环境和目标环境不一致,结果发现着手的两套代码 ...

  6. Mac Docker 挂载数据卷失败

    问题描述: docker: Error response from daemon: Mounts denied: The path /srv/docker/bind is not shared fro ...

  7. 安装conda搭建python环境(保姆级教程)

    参考文档: 安装conda搭建python环境(保姆级教程)

  8. flask入门 快速入门后台写接口【API】【Python3】【无前端】【json格式】

    目录 新建项目 虚拟环境 安装flask插件包 新建hello_world.py debug调适 四.flask应用 flask路由 变量规则 唯一的 URL / 重定向行为 flask重定向 JSO ...

  9. 一键自动化博客发布工具,用过的人都说好(cnblogs篇)

    cnblogs和其他的博客平台相比会比较复杂,需要设置的项目也比较多一些,弄懂了cnblogs的实现方式,那么你应该对selenium的整个框架使用已经烂熟于心了. 除了正常的标题,内容,摘要之外,c ...

  10. fastposter v2.15.0 从繁琐到简单,简洁好用的海报生成器

    fastposter v2.15.0 从繁琐到简单,简洁好用的海报生成器 从繁琐到简单,简洁好用的海报生成器 我很高兴向大家推荐一款令人兴奋的工具--Fastposter海报生成器.作为一名开发者,我 ...