SpringBoot如何优雅的进行参数校验
一.为什么要进行参数校验
在日常的开发过程中,我们常常需要对传入的参数进行校验,比如在web前后端分离项目中,参数校验有两个方面:
- 前端进行参数校验
- 后端进行参数校验
那这两种有什么区别呢?只完成一个可不可以呢?
答案是不可以的!
- 前端校验
前端校验主要是针对用户输入时,一些基础的错误进行提示,提升用户体验。比如:必填的选项,邮箱,网址的规则,如果前端校验不通过的话就不需要将请求转到后端。
但是:对于某些不走寻常路的用户,前端校验其实形同虚设。
2. 后端校验
后端校验是针对整个系统的业务逻辑进行校验,包含用户的权限,请求的参数等,校验的范围要大于前端.如果不做后端的校验会怎么样呢?比如前端向后端提交了一个只包含邮箱的请求,然后一些心术不正的人将该请求拷贝,改变参数为任意一段字符,然后重新发送请求,那么请求仍然能被处理,数据库就会有一条脏数据,借助此操作,可以完成一些对系统危害性更大的操作.
前端校验是辅助,后端校验是核心。后端校验必不可少。
二.后端参数校验方式
传统的参数校验一般采用大量的if else代码对参数进行一个一个的校验
传统的参数校验方式:
1 | kotlin复制代码public String checkUserDTO(UserDTO user) { |
这样的方式的话,如果参数多了那光参数校验就是一大堆,给人的感觉就是:不优雅,不专业,代码可读性也很差.
那么怎么能简单快捷的进行参数校验呢?
其实在SpringBoot项目中我们可以引入spring-boot-starter-validation来简单的进行参数校验.
三.spring-validation使用
引入依赖
粘贴请去除其中多余空格
1 | bash复制代码< !--参数校验 -- > |
参数注解列表
spring-validation是以注解的方式完成参数的校验的,而根据springboot官网的介绍,只要有JSR-303实现,例如Hibernate验证器,那么就能进行参数的校验.
这里列一下常用的注解:
- @Null
+ 说明:被注释的元素必须为 `null`
+ 适用范围:`Object`
- @NotNull
+ 说明:被注释的元素必须不为 `null`
+ 适用范围:`Object`
- @AssertTrue
+ 说明:被注释的元素必须为 `true`
+ 适用范围:`boolean`、`Boolean`
- @AssertFalse
+ 说明:被注释的元素必须为 `false`
+ 适用范围:`boolean`、`Boolean`
- @Min(value)
+ 说明:被注释的元素必须是一个数字,其值必须大于等于指定的最小值
+ 适用范围:`BigDecimal`、`BigInteger`、`byte`、`Byte`、`short`、`Short`、`int`、`Integer`、`long`、`Long`
- @Max(value)
+ 说明:被注释的元素必须是一个数字,其值必须小于等于指定的最大值
+ 适用范围:`BigDecimal`、`BigInteger`、`byte`、`Byte`、`short`、`Short`、`int`、`Integer`、`long`、`Long`
- @DecimalMin(value)
+ 说明:被注释的元素必须是一个数字,其值必须大于等于指定的最小值
+ 适用范围:`BigDecimal`、`BigInteger`、`CharSequence`、`byte`、`Byte`、`short`、`Short`、`int`、`Integer`、`long`、`Long`
- @DecimalMax(value)
+ 说明:被注释的元素必须是一个数字,其值必须小于等于指定的最大值
+ 适用范围:`BigDecimal`、`BigInteger`、`CharSequence`、`byte`、`Byte`、`short`、`Short`、`int`、`Integer`、`long`、`Long`
- @Size(max, min)
+ 说明:被注释的元素的大小必须在指定的范围内
+ 适用范围:`CharSequence`、`Collection`、`Map`、`Array`
- @Digits (integer, fraction)
+ 说明:被注释的元素必须是一个数字,其值必须在可接受的范围内
+ 适用范围:`BigDecimal`、`BigInteger`、`CharSequence`、`byte Byte`、`short Short`、`int Integer`、`long Long`
- @Past
+ 说明:被注释的元素必须是一个过去的日期
+ 适用范围:`Date`、`Calendar`、`Instant`、`LocalDate`、`LocalDateTime`、`LocalTime`、`MonthDay`、`OffsetDateTime`、`OffsetTime`、`Year`、`YearMonth`、`ZonedDateTime`、`HijrahDate`、`JapaneseDate`、`MinguoDate`、`ThaiBuddhistDate`
- @Future
+ 说明:被注释的元素必须是一个将来的日期
+ 适用范围:`Date`、`Calendar`、`Instant`、`LocalDate`、`LocalDateTime`、`LocalTime`、`MonthDay`、`OffsetDateTime`、`OffsetTime`、`Year`、`YearMonth`、`ZonedDateTime`、`HijrahDate`、`JapaneseDate`、`MinguoDate`、`ThaiBuddhistDate`
- @Pattern(value)
+ 说明:被注释的元素必须符合指定的正则表达式
+ 适用范围:`CharSequence`、`null`
+ 说明:被注释的元素必须是电子邮箱地址
+ 适用范围:`CharSequence`
- @Length
+ 说明:被注释的字符串的大小必须在指定的范围内
- @NotEmpty
+ 说明:被注释的字符串的必须非空
- @Range
+ 说明:被注释的元素必须在合适的范围内
具体使用
对于web
服务来说,为防止非法参数对业务造成影响,在Controller
层一定要做参数校验的!大部分情况下,请求参数分为如下两种形式:
POST
、PUT
请求,使用requestBody
传递参数;GET
请求,使用requestParam/PathVariable
传递参数。
下面我们简单介绍下requestBody
和requestParam/PathVariable
的参数校验
requestBody
参数校验
POST
、PUT
请求一般会使用requestBody
传递参数,这种情况下,后端使用DTO对象进行接收。只要给DTO对象加上@Validated
注解就能实现自动参数校验。
requestBody
参数校验需要两个步骤:
- 在
DTO
字段上声明约束注解
1 | kotlin复制代码public class UserDTO { |
- 在
方法
参数上声明校验注解
1 | less复制代码public Result addUser(@RequestBody @Validated UserDTO userDTO) { |
requestParam/PathVariable
参数校验
GET
请求一般会使用requestParam/PathVariable
传参
将一个个参数平铺到方法入参中。在这种情况下,必须在Controller
类上标注@Validated
注解,并在入参上声明约束注解(如@Min
等) 。
1 | less复制代码@Validated |
如果校验失败,则会抛出异常,通常会有统一异常处理
Hibernate Validator
的功能是非常强大的,它还支持分组校验
,嵌套校验
,集合校验
,自定义校验
等多种校验方式,功能非常强大.
本文转载自: 掘金