您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
SpringBoot如何优雅的进行参数校验(一)
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
SpringBoot如何优雅的进行参数校验(一)
jd****
2024-04-10
IP归属:北京
100浏览
# SpringBoot如何优雅的进行参数校验 ## 一.为什么要进行参数校验 在日常的开发过程中,我们常常需要对传入的参数进行校验,比如在web前后端分离项目中,参数校验有两个方面: - 前端进行参数校验 - 后端进行参数校验 那这两种有什么区别呢?只完成一个可不可以呢? 答案是<span style="color: #f40606">不可以</span>的! 1. 前端校验 **前端校验主要是针对用户输入时,一些基础的错误进行提示,提升用户体验**。比如:必填的选项,邮箱,网址的规则,如果前端校验不通过的话就不需要将请求转到后端。 但是:对于某些不走寻常路的用户,前端校验其实形同虚设。 2. 后端校验 **后端校验是针对整个系统的业务逻辑进行校验,包含用户的权限,请求的参数等,校验的范围要大于前端**.如果不做后端的校验会怎么样呢?比如前端向后端提交了一个只包含邮箱的请求,然后一些心术不正的人将该请求拷贝,改变参数为任意一段字符,然后重新发送请求,那么请求仍然能被处理,数据库就会有一条脏数据,借助此操作,可以完成一些对系统危害性更大的操作. **<span style="color: #7cafc2">前端校验是辅助,后端校验是核心。后端校验必不可少</span>。** ## 二.后端参数校验方式 > 传统的参数校验一般采用大量的**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_-]+)+$", user.getEmail())) { return "邮箱格式不正确"; } return "success"; } ``` 这样的方式的话,如果参数多了那光参数校验就是一大堆,给人的感觉就是:不优雅,不专业,代码可读性也很差. 那么怎么能简单快捷的进行参数校验呢? 其实在SpringBoot项目中我们可以引入**spring-boot-starter-validation**来简单的进行参数校验. ## 三.spring-validation使用 ### 引入依赖 粘贴请去除其中多余空格 ```maven < !--参数校验 -- > < 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` - @Email - 说明:被注释的元素必须是电子邮箱地址 - 适用范围:`CharSequence` - @Length - 说明:被注释的字符串的大小必须在指定的范围内 - @NotEmpty - 说明:被注释的字符串的必须非空 - @Range - 说明:被注释的元素必须在合适的范围内 ### 具体使用 对于`web`服务来说,为防止非法参数对业务造成影响,在`Controller`层一定要做参数校验的!大部分情况下,请求参数分为如下两种形式: 1. `POST`、`PUT`请求,使用`requestBody`传递参数; 2. `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; } ``` - **在`方法`参数上声明校验注解** ```java@PostMapping("/add") 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<String> getByAccount(@Length(min = 6, max = 11) @NotNull String account) { // 校验通过,才会执行业务逻辑处理 UserDTO userDTO = new UserDTO(); userDTO.setAccount(account); return Bizmessage.success(userDTO); } } ``` >如果校验失败,则会抛出异常,通常会有统一异常处理 > `Hibernate Validator`的功能是非常强大的,它还支持`分组校验`,`嵌套校验`,`集合校验`,`自定义校验`等多种校验方式,功能非常强大.
上一篇:京东保险UED AIGC 项目总结
下一篇:从零开始搭建云呼叫中心之FreeSwitch实战
jd****
文章数
2
阅读量
0
作者其他文章
01
SpringBoot如何优雅的进行参数校验(一)
SpringBoot如何优雅的进行参数校验一.为什么要进行参数校验在日常的开发过程中,我们常常需要对传入的参数进行校验,比如在web前后端分离项目中,参数校验有两个方面:前端进行参数校验后端进行参数校验那这两种有什么区别呢?只完成一个可不可以呢?答案是不可以的!前端校验前端校验主要是针对用户输入时,一些基础的错误进行提示,提升用户体验。比如:必填的选项,邮箱,网址的规则,如果前端校验不通过的话就不
01
从零开始搭建云呼叫中心之FreeSwitch实战
一. 开篇在当今快速发展的数字化时代,企业对于高效率、低成本、可扩展性强的通信解决方案的需求日益增长。云呼叫中心作为一种新兴的服务模式,正逐渐取代传统的硬件呼叫中心。FreeSwitch,作为一款强大的开源通信平台,因其卓越的性能和灵活性而成为搭建云呼叫中心的理想选择。本文将从零开始,详细介绍如何使用FreeSwitch搭建一个简单的云呼叫中心。将一步步探讨FreeSwitch的安装、配置、以及如
jd****
文章数
2
阅读量
0
作者其他文章
01
从零开始搭建云呼叫中心之FreeSwitch实战
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号