Различные группы проверки параметров метода и возвращаемого значения - PullRequest
2 голосов
/ 26 февраля 2020

Я хотел бы использовать разные группы проверки для параметров метода и его возвращаемого значения. Я пытаюсь сделать аннотацию Spring @Validated для достижения этой цели. Например:

public interface UserOperations {

    @Validated({ResponseGroup.class})
    @Valid 
    User createUser(@Validated({RequestGroup.class}) @Valid User user);

}

Похоже, что возвращаемое значение фактически проверяется по ResponseGroup, однако аргумент метода user проверяется по ResponseGroup и RequestGroup. Я понимаю, почему это происходит, когда я смотрю на: org.springframework.validation.beanvalidation.MethodValidationInterceptor#invoke

Существует ли элегантный способ применить одну группу проверки к аргументу метода и другую группу проверки к возвращаемому значению?

1 Ответ

0 голосов
/ 01 марта 2020

Проблема в том, что метод MethodValidationInterceptor.invoke ищет группы проверки, определенные в аннотации @Validated для каждого метода или класса, но не для отдельных параметров. Указанные группы проверки будут применяться к параметрам, а также к возвращаемому значению.

Для того чтобы разные группы проверки применялись к параметрам и возвращаемым значениям, вам даже не нужно указывать группы внутри аннотация @Validated; вместо этого вы можете использовать @ javax.validation.groups.ConvertGroup.

@Validated
public interface UserOperations {

    @NotNull
    @Valid
    @ConvertGroup(from = Default.class, to = User.Existing.class)
    User create(@NotNull @Valid @ConvertGroup(from = Default.class, to = User.New.class) User user);
}

public interface User {

    @Email(groups = {New.class, Existing.class})
    String getEmail();

    @Null(groups = {Existing.class})
    @NotNull(groups = {New.class})
    String getPassword();

    interface Existing {
    }

    interface New {
    }
}

Учитывая вышесказанное, когда вызывается UserOperations.create, аргумент для user будет проверен по группе New (must иметь ненулевой пароль), в то время как возвращаемое значение будет проверено по группе Existing (должен иметь нулевой пароль).

В качестве примечания, я понял, что валидация метода Spring не ведет себя точно точно так же, как и проверка c Spring MVC в @Valid @RequestBody. Кроме того, если проверка метода включена для контроллера (имеет аннотацию @Validated для класса), то один и тот же аргумент метода @RequestBody будет проверен дважды: один раз при проверке стандартного метода-перехватчика и один раз MVC. Чтобы избежать проверки MVC на @RequestBody аргументах данного контроллера, я сделал следующее:

@RestController
public class UserController implements UserOperations {
    ... 

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(null);
    }

    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...