web-dev-qa-db-ja.com

Spring Bootアプリケーションの起動中に、MethodArgumentNotValidExceptionにマップされたあいまいな@ExceptionHandlerメソッドを取得する

リクエストパラメータからの電子メール属性が適切な形式であるかどうかを検証するために、Springコントローラの1つにカスタム例外ハンドラクラスを作成しました。そこで、ResponseEntityExceptionHandlerクラスを拡張する新しいクラスを作成し、@ExceptionHandlerでメソッドを作成しました。

しかし、春のブートアプリケーションの起動中に、プロジェクトの実行を停止する例外を下回っています。誰かが私がこれを解決するのを手伝ってもらえますか?

サーバー起動時の例外:

org.springframework.beans.factory.BeanCreationException:クラスパスリソース[org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration $ EnableWebMvcConfiguration.class]で定義された「handlerExceptionResolver」という名前のBeanの作成エラー:ファクトリメソッドによるBeanのインスタンス化に失敗しました。
ネストされた例外はorg.springframework.beans.BeanInstantiationExceptionです:[org.springframework.web.servlet.HandlerExceptionResolver]のインスタンス化に失敗しました:ファクトリメソッド 'handlerExceptionResolver'が例外をスローしました。
ネストされた例外はJava.lang.IllegalStateExceptionです:[class org.springframework.web.bind.MethodArgumentNotValidException]にマップされたあいまいな@ExceptionHandlerメソッド:{public com.TestVO com.handler.exception.TestExceptionHandler.methodArgumentNotValidException(org。 springframework.web.bind.MethodArgumentNotValidException)、public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(Java.lang.Exception、org.springframework.web.context。 request.WebRequest)はJava.lang.Exceptionをスローします}

MethodArgumentNotValidExceptionを処理するカスタムクラス:

@ControllerAdvice
public class ExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ErrorVO processValidationError(MethodArgumentNotValidException ex) {
        BindingResult result = ex.getBindingResult();
        List<FieldError> fieldErrors = result.getFieldErrors();
        FieldError fieldError = fieldErrors.get(0);
        ErrorVO dto = new ErrorVO(fieldError.getDefaultMessage());
        return dto;
    }
}

あいまいさは、同じメソッド(両方のクラスに@ExceptionHandler)があるためです-ResponseEntityExceptionHandler、MethodArgumentNotValidException。この問題を回避するには、オーバーライドされたメソッドを次のように記述する必要があります-

   @Override
   protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                 HttpHeaders headers, HttpStatus status, WebRequest request) {
          String errorMessage = ex.getBindingResult().getFieldErrors().get(0).getDefaultMessage();
          List<String> validationList = ex.getBindingResult().getFieldErrors().stream().map(fieldError->fieldError.getDefaultMessage()).collect(Collectors.toList());
          LOGGER.info("Validation error list : "+validationList);
          ApiErrorVO apiErrorVO = new ApiErrorVO(errorMessage);
          apiErrorVO.setErrorList(validationList);
          return new ResponseEntity<>(apiErrorVO, status);
   }
12

ここで発生する問題は予想されることです。 Spring ResponseEntityExceptionHandlerを効果的に拡張しています。これには、デフォルトで、独自の@ExceptionHandlerアノテーションにMethodArgumentNotValidExceptionの宣言がすでに含まれています。

これは、クラスのソースから簡単に確認できます。

https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/Java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler。 Java

これが、ログにこのビットのエラーが表示される理由です。

Java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException]

上記のすべてに基づいて、独自の例外ハンドラメソッドを削除し、そこからオーバーライドする必要があります。

4
akortex91

SpringにはResponseEntityExceptionHandler用のMethodArgumentNotValidExceptionが組み込まれています。したがって、許可されていない同じ例外に対して2つのハンドラーがあります。

ResponseEntityExceptionHandler.handleMethodArgumentNotValid()のオーバーライドを試みることができます。

0
KevKosDev