SpringBoot 校验真实业务场景,你有遇到过吗?

SpringBoot 校验真实业务场景,你有遇到过吗?

0 前言

  • 我在公司进行业务开发时,遇到这样一个问题,我需要对前端提交的表单数据进行校验,但是校验顺序是随机的,不满足业务要求。在这里使用修改密码这个功能进行举例:修改密码时,需要输入原密码、新密码、确认新密码,因此这 3 项都不能为空。但如果前端表单里,这 3 项都不填,那么后端使用 @Valid + @NotBlank 进行校验时,校验顺序是随机的。
  • 下面看我是如何控制校验顺序的吧

1 随机顺序演示

  • 接收前端表单数据对象:

    /**
     * 传参
     * @Author Jasper
     * @Time 2024/01/28
     */
    @Data
    public class Param {
        /** 原密码 */
        @NotBlank(message = "原密码不能为空")
        @Length(min = 6, max = 18, message = "密码长度必为6~18位!")
        private String oldPassword;
    
        /** 新密码 */
        @NotBlank(message = "新密码不能为空")
        @Length(min = 6, max = 18, message = "密码长度必为6~18位!")
        private String newPassword;
    
        /** 确认新密码 */
        @NotBlank(message = "确认新密码不能为空")
        @Length(min = 6, max = 18, message = "密码长度必为6~18位!")
        private String confirmNewPassword;
    }
    
  • Controller 层代码:

    /**
     * 前端控制器
     * @Author Jasper
     * @Time 2024/01/28
     */
    @PostMapping("/modifyPassword")
    public R<String> modifyPassword(@RequestBody @Valid Param param){
    	return userService.modifyPassword(param);
    }
    
  • 多次发送请求后,发现校验顺序是随机的,如下图所示:
    SpringBoot 校验真实业务场景,你有遇到过吗?_第1张图片

2 如何控制校验顺序

  • 经过上述演示,确认校验顺序是随机的,因此对代码进行改造,需要使用到 @GroupSequence 注解
  • 定义一个接口,@GroupSequence 注解里定义校验顺序
    import javax.validation.GroupSequence;
    
    /**
     * 定义校验顺序
     * @Author Jasper
     * @Time 2024/01/28
     */
    @GroupSequence({ValidGroup.First.class, ValidGroup.Second.class, ValidGroup.Third.class})
    public interface ValidGroup {
    
        interface First{
    
        }
    
        interface Second{
    
        }
    
        interface Third{
    
        }
    }
    
  • 接收前端表单数据对象:设置 groups 属性,定义校验顺序
    /**
     * 传参
     * @Author Jasper
     * @Time 2024/01/28
     */
    @Data
    public class Param {
        /** 原密码 */
        @NotBlank(groups = {ValidGroup.First.class}, message = "原密码不能为空")
        @Length(min = 6, max = 18, message = "密码长度必为6~18位!")
        private String oldPassword;
    
        /** 新密码 */
        @NotBlank(groups = {ValidGroup.Second.class}, message = "新密码不能为空")
        @Length(min = 6, max = 18, message = "密码长度必为6~18位!")
        private String newPassword;
    
        /** 确认新密码 */
        @NotBlank(groups = {ValidGroup.Third.class}, message = "确认新密码不能为空")
        @Length(min = 6, max = 18, message = "密码长度必为6~18位!")
        private String confirmNewPassword;
    }
    
  • Controller 层代码:

    注意:这里不再使用 @Valid 注解,而是使用 @Validated 注解,并传入自定义接口的 class 类型对象(总校验分组对象)

    /**
     * 前端控制器
     * @Author Jasper
     * @Time 2024/01/28
     */
    @PostMapping("/modifyPassword")
    public R<String> modifyPassword(@RequestBody @Validated(ValidGroup.class) Param param){
    	return userService.modifyPassword(param);
    }
    
  • 多次发送请求,发现校验顺序是由代码控制的了,如图所示:
    SpringBoot 校验真实业务场景,你有遇到过吗?_第2张图片
  • 这样就达到了控制校验顺序的目的了,其他小伙伴还有别的方法吗?可以评论区讨论哦~
  • 创作不易,感谢阅读,若遇到问题,可以关注此微信gzh:EzCoding 留言反馈,希望更够帮助到您

你可能感兴趣的:(spring,boot,后端,java)