后端接口开发-Spring Validation检查请求参数 如判空@NotNull ,限制取值空间@Range

背景: 服务器端对客户端提交的请求参数的值应该保持"不信任"的态度。个人认为这点可内化设计原则了,哪怕客户端软件(网页、手机APP等)有严格的检查机制,主要原因在于:

  • 客户端软件存在客户端软件被篡改的可能
  • 某些项目可能有多种不同的客户端(既有网页端,又有手机端,甚至还有其它客户端),开发人员各异意识不到位,检查规则可能并不统一

所以,必须在服务器端进行检查!来保证各请求参数的有效性。

注意: 一为提高用户体验,二为缓解服务器压力!即使服务器端存在检查请求参数的机制,客户端仍有必要对即将提交的请求参数进行检查

一、 Spring Validation框架

Spring Validation框架是用于检查请求参数的基本格式 的框架。

例如,@NotNull检查某个请求参数是否为null、@Length检查某个字符串的长度、@NotEmpty检查某个字符串是否为空字符串、@Range检查数字值的区间等等。

在Spring Boot项目,在pom.xml添加spring-boot-starter-validation依赖项即可使用它:

xml 复制代码
<!-- Spring Boot Validation依赖项,用于检查请求参数的基本格式 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

二、检查实体类的请求参数

当需要对POJO类型的请求参数进行检查时:

1.在处理请求的方法的被检查参数上添加@Valid注解,表示需要对此参数进行检查,例如:

java 复制代码
    //在线文档注解
    @ApiOperation("添加相册") //接口名注解
    @ApiOperationSupport(order = 2)//接口展示排序
    //直接网络请求添加
    //http://localhost:8080/album/add?name=TestAlbum001&description=TestDescription001&sort=88
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public JsonResult addNewAlbum(@Valid AlbumAddNewDTO albumAddNewDTO) {
        albumService.addNew(albumAddNewDTO);
        return JsonResult.ok();
    }

2.在POJO类的属性上,添加你需要的检查注解(根据不同的检查规则,使用不同的检查注解)

例如,当某个请求参数是必须提交的,可以添加@NotNull注解,例如,在AlbumAddNewDTO类中:

java 复制代码
@Data
public class AlbumAddNewDTO implements Serializable {
    @ApiModelProperty(value = "相册名称", required = true, example = "小米手机的相册")
    @NotNull(message = "添加相册失败,必须提交相册名称!")
    private String name;
    @ApiModelProperty(value = "描述", example = "简单相册")
    private String description;
    @ApiModelProperty(value = "排序权重", example = "100")
    private Integer sort;
}

以上实现对name属性进行"不允许为null"的检查,如果客户端提交的请求参数中不包含name属性,服务器端将响应400错误。

3.如果相对该错误进行捕捉,和响应,如下:

效果

正常上线项目,会对异常进行特殊处理,此处仅打印异常日志

三、检查未封装的请求参数

如果某些请求的参数数量较少,或各参数并不相关,通常不会将参数封装到POJO类型中。

1.在当前类上添加@Validated注解,例如:

java 复制代码
@RestController
@Validated // 新增
public class AlbumController {
    // 暂不关心类内部的代码
}

2.在需要检查的参数上添加检查注解,

例如:检查是否相册id是否为空@NotNull 检查相册id是否在一定范围内@Range(min = 1, max = 20)

java 复制代码
    //在线文档注解
    @ApiOperation("根据相册id删除相册")//接口名注解
    @ApiImplicitParam(name = "id", value = "相册序号", required = true,
            example = "11", dataType = "Long")//参数名注解
    @ApiOperationSupport(order = 1)//接口展示排序
    //直接网络请求删除
    //http://localhost:8080/album/delete/byId?id=2
    @RequestMapping(value = "/delete/byId", method = RequestMethod.GET)
    public JsonResult deleteAlbumById( @NotNull @Range(min = 1, max = 20) Long id) {
        // "deleteAlbumById.id: 需要在1和20之间
        log.debug("开始处理【根据相册id删除】的请求,参数123:{}", id);
        try {
            albumService.deleteAlbumById(id);
            return JsonResult.ok();
        } catch (Exception e) {
            String message = e.getMessage();
            log.error("deleteAlbumById Exception {}", message);
            return JsonResult.fail(ServiceCode.ERR_CUSTOM, message);
        }

实际效果:服务器端将响应500错误,

我这边笼统捕获一下就是

四、常用的检查注解

1.使用Validation框架检查数据的基本格式时,常用的检查注解有:

  • @NotNull:不允许为null值,即客户端必须提交此参数
    • 可用于任何类型的参数
  • @NotEmpty:不允许为空字符串,即不允许是长度为0的字符串
    • 仅用于字符串类型的参数
  • @NotBlank:不允许为空白的字符串,即不允许仅由空格、TAB制表位、换行等空白组成的字符串
    • 仅用于字符串类型的参数
  • @Length:限制字符串的长度,也可以用于检查集合等数据的长度,但不常见
    • 通常仅用于字符串类型的参数
  • @Pattern:通过正则表达式检查字符串的格式,此注解的regexp属性是定义正则表达式的属性
    • 仅用于字符串类型的参数
  • @Min:限制最小值
    • 仅用于整型数值类型的参数
  • @Max:限制最大值
    • 仅用于整型数值类型的参数
  • @Range:限制取值区间,默认最小值为0,最大值是long类型的上限值
    • 仅用于整型数值类型的参数

**提示:**在源代码中,有2套检查注解的包,例如@NotNull@Range这2个注解就在不同的包下。

2.关于检查注解的使用:

  • @NotNull注解可以添加在任何类型的请求参数上,
  • 所有检查注解都有message属性,用于配置检查失败时的提示文本
  • 每个被检查的请求参数都可以同时添加多个检查注解 ,如同时使用@NotNull与另1个或多个检查注解。

创造价值,乐哉分享!

相关推荐
阿伟*rui2 小时前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
XiaoLeisj3 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck4 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei4 小时前
java的类加载机制的学习
java·学习
码农小旋风5 小时前
详解K8S--声明式API
后端
Peter_chq5 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml45 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~5 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616886 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7896 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot