【问题标题】:Is there a declarative way to validate request parameters depending from one of request fields?是否有根据请求字段之一验证请求参数的声明性方法?
【发布时间】:2018-03-05 14:11:53
【问题描述】:

我正在寻找类似 JSR-303 Validation Groups 的东西(bean 验证,当您在控制器中使用 @Validated(GroupName.class) 标记方法参数并在需要的请求类字段中指定组时),但它应该决定如何根据请求字段之一在运行时进行验证。

例如,如果我们有这样的控制器类

@Controller
public class MyController {
    @Autowired
    private MyService myService;

    @ResponseBody
    @RequestMapping(value = "/path", method = RequestMethod.PUT)
    public ResponseVo storeDetail(/*maybe some annotation here*/ DetailRequestVo requestVo) {
        return myService.storeDetail(requestVo);
    }

    class DetailRequestVo {
        String type;
        Long weight;
        Long radius;
    }
}

我们希望根据 type 字段值进行验证:如果 type = "wheel" 则应显示半径和 weight 字段,如果 type = "engine" 则应仅显示 weight 字段。

Spring(自 3.2.17 起)是否提供 API 以更具声明性的方式实现这些规则? org.springframework.validation.Validator 在这里看起来不是一个选项,因为它的方法 boolean supports(Class<?> clazz) 基于类信息而不是实例信息来决定。

提前致谢

【问题讨论】:

    标签: java spring validation http-request-parameters


    【解决方案1】:

    不确定 Spring,但您可以使用普通的 JSR-303 为类本身使用自定义验证器来做到这一点......就像

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.TYPE })
    @Constraint(validatedBy = TypeValidator.class)
    @Documented
    public @interface ValidType {
          ...
    }
    
    public class TypeValidator implements ConstraintValidator<ValidType , Object> {
    
        public boolean isValid(final Object target, final ConstraintValidatorContext context) {
            DetailRequestVo request = (DetailRequestVo) target;
            // do your checks here
    }
    

    和使用一样

    @ValidType
    class DetailRequestVo {
            String type;
            Long weight;
            Long radius;
        }
    

    由于自定义验证器可以访问整个 DetailRequestVo-Object,因此您可以根据字段 B 等检查字段 A。

    【讨论】:

    • 感谢您的回答。确实,这是一种重复使用相同检查并以声明方式进行检查的好方法,但声明自定义注释只是为了在一个地方检查字段是不是有点矫枉过正?
    • 也许,但据我所知,仍然是满足您要求的最简单/最具声明性的一种
    猜你喜欢
    • 2016-09-25
    • 2021-03-11
    • 2015-09-05
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多