自定义注解可以抛出自定义异常,而不是MethodArgumentNotValidException?

2024-02-29

我有一个 @ExceptionHandler(MethodArgumentNotValidException.class) 在验证失败时返回 HTTP 代码 400。我创建了一个自定义注释,需要将 HTTP 代码更改为 422。但是,由于异常处理程序已经使用 @ResponseStatus(code = HttpStatus.BAD_REQUEST) 注释,我该怎么做呢?

我认为也许可以使我的自定义注释抛出自定义异常,然后捕获它。那可能吗?如何?

我的休息控制器建议:

@RestControllerAdvice
public class ManipuladorDeExcecoes {

  @Autowired
  MessageSource messageSource;

  @ResponseStatus(code = HttpStatus.BAD_REQUEST)
  @ExceptionHandler(MethodArgumentNotValidException.class)
  public List<ErroPadrao> handle(MethodArgumentNotValidException exception) {
    List<ErroPadrao> listaDeErros = new ArrayList<>();
    List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();

    fieldErrors.forEach(e -> {
      String mensagem = messageSource.getMessage(e, LocaleContextHolder.getLocale());
      ErroPadrao erro = new ErroPadrao(e.getField(), mensagem);
      listaDeErros.add(erro);
    });

    return listaDeErros;
  }
}

我的自定义注释:

@Constraint(validatedBy = ValorUnicoValidator.class )
@Target({ FIELD })
@Retention(RUNTIME)
public @interface ValorUnico {
  String message() default "O valor informado já existe no banco de dados";

  String campo();
  Class<?> tabela();
  boolean removeStrings() default false;

  Class<?>[] groups() default {};
  Class<? extends Payload>[] payload() default {};
}

我的验证器:

public class ValorUnicoValidator implements ConstraintValidator<ValorUnico, Object> {

  @PersistenceContext
  EntityManager entityManager;

  private String campo;
  private Class<?> tabela;
  private boolean removeStrings;

  @Override
  public void initialize(ValorUnico constraintAnnotation) {
    this.campo = constraintAnnotation.campo();
    this.tabela = constraintAnnotation.tabela();
    this.removeStrings = constraintAnnotation.removeStrings();
  }

  @Override
  public boolean isValid(Object value, ConstraintValidatorContext context) {
    if (removeStrings) {
      value = value.toString().replaceAll("[^0-9]", "");
    }

    Boolean valorJaExiste = entityManager
            .createQuery("SELECT COUNT(t) < 1 FROM " + tabela.getName() + " t WHERE "
                    + campo + " = :pValor", Boolean.class)
            .setParameter("pValor", value)
            .getSingleResult();

    return valorJaExiste;
  }
}

我不知道有什么方法可以让验证器抛出自定义异常。Here https://stackoverflow.com/a/62896541/13018875,有人通过手动抛出自定义异常来解决这个问题(在每个具有相关类型参数的请求映射中);你可以做他们所做的,然后写一个@ExceptionHandler为您的自定义异常类。不过我认为还有更好的方法。

您可以检查消息中是否存在失败的约束@ExceptionHandler,并据此返回不同的状态码。 (您需要删除@ResponseStatus注解并更改方法的返回类型,但有许多允许的返回类型@ExceptionHandler方法——包括ResponseEntity,您可以将其状态设置为您喜欢的任何内容。)因此,类似

@ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Void> handleInvalid(MethodArgumentNotValidException e) {
        for (FieldError err: e.getFieldErrors()) {
            if (err.getDefaultMessage().equals("O valor informado já existe no banco de dados")) {
                return ResponseEntity.unprocessableEntity().build();
            }
        }

        return ResponseEntity.badRequest().build();
    }

显然,您需要将该消息字符串转换为常量,因为您不想记住在@ExceptionHandler方法和注释本身。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义注解可以抛出自定义异常,而不是MethodArgumentNotValidException? 的相关文章

随机推荐