网站首页 > 技术文章 正文
SpringBoot如何优雅的进行参数校验
一.为什么要进行参数校验
在日常的开发过程中,我们常常需要对传入的参数进行校验,比如在web前后端分离项目中,参数校验有两个方面:
- 前端进行参数校验
- 后端进行参数校验
那这两种有什么区别呢?只完成一个可不可以呢?
答案是不可以的!
- 前端校验
- 前端校验主要是针对用户输入时,一些基础的错误进行提示,提升用户体验。比如:必填的选项,邮箱,网址的规则,如果前端校验不通过的话就不需要将请求转到后端。
- 但是:对于某些不走寻常路的用户,前端校验其实形同虚设。
- 后端校验
- 后端校验是针对整个系统的业务逻辑进行校验,包含用户的权限,请求的参数等,校验的范围要大于前端.如果不做后端的校验会怎么样呢?比如前端向后端提交了一个只包含邮箱的请求,然后一些心术不正的人将该请求拷贝,改变参数为任意一段字符,然后重新发送请求,那么请求仍然能被处理,数据库就会有一条脏数据,借助此操作,可以完成一些对系统危害性更大的操作.
- 前端校验是辅助,后端校验是核心。后端校验必不可少。
二.后端参数校验方式
传统的参数校验一般采用大量的if else代码对参数进行一个一个的校验
传统的参数校验方式:
public String checkUserDTO(UserDTO user) {
if (StringUtils.isEmpty(user.getName())) {
return "用户名不能为空";
}
if(StringUtils.isEmpty(user.getEmail())) {
return "邮箱不能为空";
}
if(StringUtils.isEmpty(user.getAccount())) {
return "账号不能为空";
}
if (user.getAccount().length() < 6 || user.getAccount().length() > 11) {
return "账号长度必须是6-11个字符";
}
if (!Pattern.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+#34;, user.getEmail())) {
return "邮箱格式不正确";
}
return "success";
}
这样的方式的话,如果参数多了那光参数校验就是一大堆,给人的感觉就是:不优雅,不专业,代码可读性也很差.
那么怎么能简单快捷的进行参数校验呢?
其实在SpringBoot项目中我们可以引入spring-boot-starter-validation来简单的进行参数校验.
三.spring-validation使用
引入依赖
粘贴请去除其中多余空格
< !--参数校验 -- >
< dependency >
< groupId>org.springframework.boot < /groupId>
< artifactId>spring-boot-starter-validation< /artifactId>
< /dependency>
参数注解列表
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字段上声明约束注解
- public class UserDTO { private Long Id; @NotNull @Length(min = 2, max = 10) private String name; @NotNull @Length(min = 6, max = 20) private String account; @NotNull @Email private String email; }
- 在方法参数上声明校验注解
public Result addUser(@RequestBody @Validated UserDTO userDTO) {
// 校验通过,才会执行业务逻辑处理
return Result.ok();
}
requestParam/PathVariable参数校验
GET请求一般会使用requestParam/PathVariable传参
将一个个参数平铺到方法入参中。在这种情况下,必须在Controller类上标注@Validated注解,并在入参上声明约束注解(如@Min等)。
@Validated
@RestController
public class UserController {
// 路径变量
@GetMapping("{userId}")
public Result detail(@PathVariable("userId") @Min(10000000000000000L) Long userId) {
// 校验通过,才会执行业务逻辑处理
UserDTO userDTO = new UserDTO();
userDTO.setId(userId);
return Bizmessage.success(userDTO);
}
// 查询参数
@GetMapping("getByAccount")
public BizMessage getByAccount(@Length(min = 6, max = 11) @NotNull String account) {
// 校验通过,才会执行业务逻辑处理
UserDTO userDTO = new UserDTO();
userDTO.setAccount(account);
return Bizmessage.success(userDTO);
}
}
如果校验失败,则会抛出异常,通常会有统一异常处理
Hibernate Validator的功能是非常强大的,它还支持分组校验,嵌套校验,集合校验,自定义校验等多种校验方式,功能非常强大.
猜你喜欢
- 2024-10-13 谈谈springboot 获取前端json数据几种方法
- 2024-10-13 在Spring Boot中如何获取到Request对象?
- 2024-10-13 SpringBoot:如何优雅地进行响应数据封装、异常处理
- 2024-10-13 SpringBoot实现接口防抖的几种方案,杜绝重复提交
- 2024-10-13 @PostMapping @GetMapping注解 postmapping注解接收参数
- 2024-10-13 如何在SpringBoot中动态过滤JSON响应正文
- 2024-10-13 WebSocket 集群解决方案 websocket500
- 2024-10-13 SpringBoot跨系统调用接口方案 springboot跨越设置
- 2024-10-13 IntelliJ IDEA必装插件以及SpringBoot使用小技巧合集
- 2024-10-13 springboot整合vue2实现大文件分片上传、秒传、断点续传
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)