Java BeanValidation的上下文相关验证

Java BeanValidation的上下文相关验证,java,bean-validation,Java,Bean Validation,我是JSR303BV的忠实粉丝,但在我当前的项目中,我有很多“上下文相关验证”,我没有找到任何合理的方法来用BV实现它们。 基本上,验证规则可以依赖于 已登录用户(存储在http请求中) 我们操作的用户-用户id是RESTURL的路径参数,如/foo/bar/user/1/sth 这两个 举个小例子: class Alphabet{ @Valid private Alpha a; @Valid private Beta b; @Valid private Gamma g; } 和验证规则:

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

  • 已登录用户(存储在http请求中)
  • 我们操作的用户-用户id是RESTURL的路径参数,如/foo/bar/user/1/sth
  • 这两个
举个小例子:

class Alphabet{
@Valid
private Alpha a;
@Valid
private Beta b;
@Valid
private Gamma g;
}
和验证规则: 如果其id将在URL中提供的用户具有“admin”角色,则“a”、“b”、“g”属性都不能为空。如果它只有“用户”角色“a”不能为空,其他道具必须为空

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

您可以使用:

根据当前用户的角色,您可以在调用验证程序时指定
AdminChecks
UserChecks
,例如,对于管理员检查:

Validator validator = ...;
Set<ConstraintViolation<Alphabet>> violations = validator.validate(
    new Alphabet(),
    AdminChecks.class
);
Validator-Validator=。。。;
设置冲突=validator.validate(
新字母表(),
管理员类
);

Thx Gunnar以获取答案。我过分简化了我的示例。真正的验证规则是:如果用户是来宾,并且属于不允许更改来宾gamma的工作组,则gamma属性必须为null,但如果工作组允许更改来宾gamma,则gamma属性不得为null。类似的规则适用于Beta、Alpha和其他属性。所有这些属性都是独立的-您可以拥有允许来宾使用gamma和beta但不允许使用alpha的工作组-任何可能的组合。我不能用验证组对其建模,必须使用类级约束
Validator validator = ...;
Set<ConstraintViolation<Alphabet>> violations = validator.validate(
    new Alphabet(),
    AdminChecks.class
);