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

#java #spring #spring-boot #validation #kotlin

#java #весна #пружинный ботинок #валидация #котлин

Вопрос:

Есть ли способ настроить проверку 2 параметров запроса, поступающих в конечную точку весной? Я хотел бы иметь возможность проверять их с помощью моей пользовательской функции. Что-то вроде добавления аннотации к параметрам запроса или к функции, в которой находятся эти параметры, и принудительной проверки этих параметров другой пользовательской функцией.
Мне нужно использовать оба параметра одновременно, потому что результат проверки одного из них зависит от значения другого.
Я искал и нашел несколько решений с пользовательскими аннотациями ограничений, но, судя по тому, что я прочитал, это, похоже, не решает мою проблему.

Ответ №1:

Как справедливо упоминалось, использование valiktor — лучший вариант. Я также использовал его в нашем продукте, и он работает как заклинание.

Ниже приведен пример фрагмента кода, показывающий, как вы используете его для сравнения двух свойств одного и того же класса.

 fun isValid(myObj: Myobj): Boolean {
    validate(myObj) {
    validate(MyObj::prop1).isGreaterThanOrEqualTo(myobj.prop2)
}
 

Valiktor выдает исключение с соответствующим сообщением, если проверка завершилась неудачно. Он также позволяет вам создавать пользовательские сообщения об исключениях, если вы хотите.

Теперь все, что вам нужно сделать, это создать класс для вашего RequestBody и явно проверить ваши условия с помощью метода isValid() или переместить его в блок инициализации и сделать это неявно.

Valiktor имеет большое количество проверок по сравнению с JSR380, где создание пользовательской проверки немного запутанно по сравнению с Valiktor.

Ответ №2:

Если вы собираетесь использовать параметры запроса для создания POJO, то вы можете просто использовать Javax Validation API .

 public class User {

    private static final long serialVersionUID = 1167460040423268808L;

    @NotBlank(message = "ID cannot be to empty/null")
    private int id;

    @NotBlank(message = "Group ID cannot be to empty/null")
    private String role;

    @NotBlank(message = "Email cannot be to empty/null")
    private String email;

    @NotNull(message = "Password cannot be to null")
    private String password;
}
 

Для проверки —

 @PostMapping("/new")
public String save(@ModelAttribute @Validated User user, BindingResult bindingResult, ModelMap modelMap) throws UnknownHostException {
if (!bindingResult.hasErrors()) {
    // Proceed with business logic
} else {
        Set<ConstraintViolation<User>> violations = validator.validate(user);
        List<String> messages = new ArrayList<>();
        if (!violations.isEmpty()) {
            violations.stream().forEach(staffConstraintViolation -> messages.add(staffConstraintViolation.getMessageTemplate()));
            modelMap.addAttribute("errors", messages);
            Collections.sort(messages);
        }
        return "new~user";
    }
}
 

Ответ №3:

Вы можете написать пользовательский валидатор, используя проверку валидатора :: https://docs.spring.io/spring-framework/docs/3.0.0.RC3/reference/html/ch05s02.html Пример :: https://www.baeldung.com/spring-data-rest-validators

Ответ №4:

valiktor — действительно хорошая библиотека для проверки.

Вы можете сделать что-то вроде:

 data class ValidatorClass(val field1: Int, val field2: Int) {
    init {
        validate(this) {
            validate(ValidatorClass::field1).isPositive()
            validate(ValidatorClass::field2).isGreaterThan(field1)
        }
    }
}
 

сделать параметр запроса не обязательным:

 @RequestMapping(path = ["/path"])
fun fooEndPoint(@RequestParam("field1", required = false) field1: Int,
                @RequestParam("field2", required = false) field2: Int) {
    ValidatorClass(field1, field2) //it will throw an exception if validation fail
}
 

Вы можете обрабатывать исключения, используя try-catch или используя и ExceptionHandler определенные valiktor.

Используя valiktor, вы можете проверять поля в зависимости от других полей. Вы можете создать один файл kotlin, в который вы записываете все классы, которые вы используете для проверки полей из запросов, и таким же образом вы можете использовать valiktor в @RequestBody своих моделях для его проверки.