Я работаю над API REST с использованием Spring, и я пытаюсь создать новый пользовательский валидатор с двумя проверками.
Для каждого валидатора я хочу вернуть пользователям другой HTTP-КОД, но я застрял на нем, я просто знаю, что могу вернуть логическое значение в методе isValid.
Я надеюсь, что кто-нибудь сможет мне помочь или подскажет, как лучше сделать это.
@RestController
@RequestMapping("user")
public class UserController {
@PostMapping
public ResponseEntity<?> addUser(@Valid @RequestBody User
user, Errors errors) {
//Here I don't now How to read just one error from Validator class, I just want to return 1 error using the HTTP CODE
if (errors.hasErrors()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT); //I'm just using a generic but I want to use the returned by Validator which has 2 validations and should return different errors
}
return new ResponseEntity<>(user, HttpStatus.OK);
}
}
public class User {
@NotNull
private final String name;
@NotNull
@UserConstraint
private final Integer age;
public User(@JsonProperty("name") String name, @JsonProperty("age") Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
@Documented
@Constraint(validatedBy = UserValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserConstraint {
String message() default "Invalid age";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class UserValidator implements ConstraintValidator<UserConstraint, Integer> {
@Override
public void initialize(UserConstraint constraintAnnotation) {
}
@Override
public boolean isValid(Integer age, ConstraintValidatorContext context) {
if (age > 60) {
//Here I want to return HTTP CODE 402 to the user
return false;
} else if (age < 18) {
//Here I want to return HTTP CODE 422 to the user
return false;
}
return true;
}
}
Как видите, я пытаюсь проверить возраст и хочу вернуть пользователям другой HTTP-КОД.
Мне нужно вернуть разные HTTP-КОДЫ и сообщения для каждого из них. Кроме того, мне нужно применить больше случаев к этому методу (с большей логикой).
Я предлагаю использовать ThreadLocal для установки результата проверки в UserValidator, затем вы можете получить значение в UserController для проверки




Вы можете попробовать что-то вроде этого: в методе isValid в UserValidator генерировать новое собственное исключение, например UnderageUserException. Класс UnderageException должен расширять RuntimeException, и вам необходимо аннотировать это с помощью @ResponseStatus (value = HttpStatus.UNPROCESSABLE_ENTITY) для 422. https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpStatus.html <---- здесь у вас есть список кодов. Затем создайте контроллер с аннотацией @AdviceController, который будет обрабатывать эти исключения из всех классов контроллеров. редактировать: https://www.baeldung.com/exception-handling-for-rest-with-spring вот вам хороший путеводитель по этому поводу
Можно было скинуть ResponseStatusException
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "error message");
Почему бы не использовать стандартные валидаторы Min / Max по возрасту?