0

我是 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”属性都不能为空。如果它具有角色“用户”,则只有“a”不能为空,其他道具必须为空。

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

4

1 回答 1

2

您可以使用验证组

//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
);
于 2013-03-04T07:56:55.440 回答