美文网首页
SpringBoot参数校验-解决一些相同字段不同校验逻辑的校验

SpringBoot参数校验-解决一些相同字段不同校验逻辑的校验

作者: Java及SpringBoot | 来源:发表于2019-12-11 13:23 被阅读0次

    个人专题目录


    SpringBoot参数校验-解决一些相同字段不同校验逻辑的校验顺序问题

    项目中遇到的问题

    springBoot中对一些参数需要不同维度的校验逻辑,但是需要控制校验顺序,校验之间有先后顺序的依赖。

    解决方案:使用JSR提供的@GroupSequence注解控制校验顺序

    分组验证

    分组接口
    public interface GroupRunCount {
    }
    
    /**
     * JSR提供的@GroupSequence注解控制校验顺序
     * 第二个组的约束验证依赖于第一个约束执行完成的结果
     * 某个Group组的校验非常耗时,并且会消耗比较大的CPU/内存
     * 一个组可以定义为其他组的序列,使用它进行验证的时候必须符合该序列规定的顺序。
     * 在使用组序列验证的时候,如果序列前边的组验证失败,则后面的组将不再给予验证
     *
     * 本例中目的是想先验证属性上面的验证规则,然后再验证自定义验证规则
     */
    @GroupSequence({Default.class, GroupRunCount.class})
    public interface Group {
    }
    
    实体类
    @Data
    @TestParamCheck(groups = GroupRunCount.class)
    public class TestParam {
    
        @NotNull(message = "{MaxCountInvalidParameterValue}")
        @Range(min = 1, max = 500, message = "{MaxCountInvalidParameterValue}")
        private Integer maxCount;
    
        @NotNull(message = "{MinCountInvalidParameterValue}")
        @Range(min = 1, max = 500, message = "{MinCountInvalidParameterValue}")
        private Integer minCount;
    
    }
    
    自定义验证注解
    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Constraint(validatedBy = TestParamValidator.class)
    @Documented
    public @interface TestParamCheck {
    
        String message() default "";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }
    
    自定义注解处理类
    public class TestParamValidator implements ConstraintValidator<TestParamCheck, TestParam> {
    
        @Autowired
        private QuotaService quotaService;
    
        @Override
        public void initialize(TestParamCheck constraintAnnotation) {
    
        }
    
        @Override
        public boolean isValid(TestParam param, ConstraintValidatorContext context) {
            Integer maxCount = param.getMaxCount();
            Integer minCount = param.getMinCount();
            if (maxCount != null && minCount != null) {
                int quotaMax = quotaService.getMax();
                String messageTemplate;
                context.disableDefaultConstraintViolation();
                if (maxCount > quotaMax) {
                    messageTemplate = "{MaxCountInvalidParameterValue}";
                    context.buildConstraintViolationWithTemplate(messageTemplate).addConstraintViolation();
                    return false;
                } else if (minCount > quotaMax) {
                    messageTemplate = "{MinCountInvalidParameterValue}";
                    context.buildConstraintViolationWithTemplate(messageTemplate).addConstraintViolation();
                    return false;
                }
            }
            return true;
        }
    
    }
    

    功能测试

    测试核心代码如下:

    Controller

    @RestController
    @RequestMapping(value = "/", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
    @Slf4j
    public class TestController {
    
        @RequestMapping
        public void testAction(HttpServletRequest request, @Validated(TestParam.Group.class)) {
            log.info("param={}", param);
        }
    
    }
    

    通过测试我们发现代码先验证属性上面的验证规则,然后再验证自定义验证规则,解决了顺序验证问题。

    本文示例代码的验证错误消息都整合了Spring的国际化,怎么整合hibernate-validator验证和Spring验证并使用Spring的国际化,下篇文章再详细介绍。

    相关文章

      网友评论

          本文标题:SpringBoot参数校验-解决一些相同字段不同校验逻辑的校验

          本文链接:https://www.haomeiwen.com/subject/hzuogctx.html