有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

BeanValidation的java上下文相关验证

我非常喜欢JSR 303 BV,但在我当前的项目中,我有很多“上下文相关验证”,我没有找到任何合理的方法来用BV实现它们。 基本上,验证规则可以依赖于

  • 已登录用户(存储在http请求中)
  • 我们操作的用户——用户的id是REST URL的路径参数,比如/foo/bar/user/1/sth
  • 这两个

举个小例子:

class Alphabet{
@Valid
private Alpha a;
@Valid
private Beta b;
@Valid
private Gamma g;
}

和验证规则: 如果将在URL中提供id的用户具有“admin”角色,则“a”、“b”、“g”属性都不能为空。如果它只有角色“user”,那么“a”不能为空,其他道具必须为空

所以基本上,这些规则可以作为Alphabet类的类级约束轻松实现,但是定制验证器需要用户的访问id,这是URL中提供的。有没有什么聪明的方法可以实现这一点,或者我必须强制所有REST客户端多次传递用户id:在URL和有效负载中,以便后者仅由BV使用。 更复杂的情况是,验证规则取决于登录的用户,因此自定义验证器必须以某种方式从ThreadLocal或HttpServletRequest访问经过身份验证的主体


共 (1) 个答案

  1. # 1 楼答案

    你可以利用validation groups

    //Define validation groups
    interface AdminChecks {}
    interface UserChecks {}
    
    //Assign the constraints to the two groups
    class Alphabet{
    
        @NotNull(groups={AdminChecks.class, UserChecks.class})
        private Alpha a;
    
        @NotNull(groups=AdminChecks.class)
        @Null(groups=UserChecksChecks.class)
        private Beta b;
    
        @NotNull(groups=AdminChecks.class)
        @Null(groups=UserChecksChecks.class)
        private Gamma g;
    }
    

    然后,根据当前用户的角色,在调用验证程序时指定AdminChecksUserChecks,例如,对于管理检查:

    Validator validator = ...;
    Set<ConstraintViolation<Alphabet>> violations = validator.validate(
        new Alphabet(),
        AdminChecks.class
    );