Обход валидатора уникальности для запроса PUT - PullRequest
0 голосов
/ 17 октября 2018

Я столкнулся с проблемой невозможности обойти ни одного валидатора, который используется для проверки уникальности имени объекта при запросах POST и PUT.Подробности приведены ниже:

Дано,

Класс UserDTO с двумя полями

private int id

@UserUniquenessValidator
private String name

Сигнатуры методов контроллера

post(@Valid @RequestBody UserDTO userDTO)

put(@PathVariable int id, @Valid @RequestBody UserDTO userDTO)

Пользовательский валидаторприменяется к имени поля

 @UserUniquenessValidator

Теперь, когда я пытаюсь отправить нового пользователя POST, пользовательский валидатор просто проверяет поле имени на соответствие другим записям в базе данных и возвращает true, если не находит ни одного, и т.-versa.

Проблема возникает каждый раз, когда отправляется запрос PUT с неизмененным полем «имя» - валидатор проверяет уникальность и не пропускает, так как уже имеет запись с указанным именем вБД.

В дополнение к этому я должен упомянуть, что ограничение не может быть применено к таблице в базе данных по причинам, которые слишком длинны для объяснения.

Есть ли хитрый ход?вокруг решения этого без необходимости загромождать код слишком много?Я хотел бы, чтобы был способ сообщить валидатору, что каждый раз, когда вводится PUT, чтобы следовать другой логике, чем для запроса POST.

1 Ответ

0 голосов
/ 17 октября 2018

Я могу предположить, что ваш валидатор уже является компонентом Spring: вы извлекаете записи базы данных, чтобы добиться уникальности имени.

При условии, что валидатор задействован только в контексте проверки запроса, вы можете внедрить прокси HttpServletRequest, чтобы дать валидатору контекст запроса

@Autowired
private HttpServletRequest request;

, из которого можно выяснитьтекущий метод HTTP.

@Override
public boolean isValid(String name, ConstraintValidatorContext context) {
    return HttpMethod.PUT.name().equals(request.getMethod()) || 
           validate(name, context);
}

private boolean validate(String name, ConstraintValidatorContext context) {
    // validate name uniqueness
    return false;
}

Чтобы избежать жесткого кодирования HttpMethod.PUT.name(), аннотация может определять String[] excludeFor:

@UserUniquenessValidator(excludeFor={"PUT"})

Я считаю имя аннотации неправильным.UserUniquenessValidator - хорошее название для класса, который обрабатывает эту аннотацию, но не для самой аннотации.Я бы назвал это @UniqueName.

...