контекстно-зависимая проверка для BeanValidation

Я большой поклонник JSR 303 BV, но в моем текущем проекте у меня много «контекстно-зависимой проверки», и я не нахожу разумного подхода к их реализации с помощью BV. В основном правила проверки могут зависеть от

  • авторизованный пользователь (он хранится в http-запросе)
  • пользователь, с которым мы действуем - идентификатор пользователя является параметром пути URL-адреса REST, например /foo/bar/user/1/sth
  • Оба эти

Небольшой пример:

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

И правило проверки: если пользователь, чей идентификатор будет указан в URL-адресе, имеет роль «admin», ни одно из свойств «a», «b», «g» не может быть нулевым. Если у него есть роль «пользователь», только «а» не должно быть нулевым, а другие реквизиты должны быть нулевыми.

Таким образом, в основном такого рода правила могут быть легко реализованы как ограничение уровня класса класса Alphabet, но пользовательскому валидатору потребуется каким-то образом получить доступ к идентификатору пользователя, который указан в URL-адресе. Есть ли какой-либо разумный способ добиться этого, или мне нужно заставить всех клиентов REST передавать идентификатор пользователя несколько раз: в URL-адресе и в полезной нагрузке, поэтому последний будет использоваться только BV. Более сложный случай, когда правило проверки зависит от вошедшего в систему пользователя, поэтому пользовательские валидаторы должны будут каким-то образом получить доступ к аутентифицированному принципалу - из ThreadLocal или HttpServletRequest.


person user62058    schedule 03.03.2013    source источник


Ответы (1)


Вы можете использовать группы проверки< /а>:

//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;
}

В зависимости от роли текущего пользователя вы затем указываете либо AdminChecks, либо UserChecks при вызове валидатора, например. вот так для проверок администратора:

Validator validator = ...;
Set<ConstraintViolation<Alphabet>> violations = validator.validate(
    new Alphabet(),
    AdminChecks.class
);
person Gunnar    schedule 04.03.2013
comment
Спасибо, Гуннар, за ответ. Я слишком упростил свой пример. Настоящее правило проверки выглядит так: если пользователь является гостем и принадлежит к рабочей группе, которая запрещает изменение гаммы для гостей, то свойство gamma должно быть нулевым, но если рабочая группа разрешает изменять гамму для гостя, то гамма не должна быть нулевой . Аналогичные правила применяются к бета-, альфа- и другим ресурсам. Все эти свойства являются независимыми — у вас могут быть рабочие группы, которые разрешают и гамма, и бета для гостей, но запрещают альфа — любая возможная комбинация. Я просто не могу смоделировать его с помощью групп проверки и должен использовать ограничения на уровне класса. - person user62058; 07.03.2013