Вернуть HTTP-КОД в настраиваемом валидаторе Spring Rest

Я работаю над API REST с использованием Spring, и я пытаюсь создать новый пользовательский валидатор с двумя проверками.

Для каждого валидатора я хочу вернуть пользователям другой HTTP-КОД, но я застрял на нем, я просто знаю, что могу вернуть логическое значение в методе isValid.

Я надеюсь, что кто-нибудь сможет мне помочь или подскажет, как лучше сделать это.

UserController.java

@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);
  }
 } 

User.java

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

}

UserConstraint.java

@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 {};
}

UserValidator.java

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-КОД.

Почему бы не использовать стандартные валидаторы Min / Max по возрасту?

Strelok 16.08.2018 00:12

Мне нужно вернуть разные HTTP-КОДЫ и сообщения для каждого из них. Кроме того, мне нужно применить больше случаев к этому методу (с большей логикой).

Candres 16.08.2018 01:19

Я предлагаю использовать ThreadLocal для установки результата проверки в UserValidator, затем вы можете получить значение в UserController для проверки

clevertension 16.08.2018 08:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
3
1 522
2

Ответы 2

Вы можете попробовать что-то вроде этого: в методе 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");

Другие вопросы по теме