Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException]

后端 未结 3 874
南笙
南笙 2020-12-24 04:53

I\'m trying to handle MethodArgumentNotValidException using @ControllerAdvice as code given below:

@ControllerAdvice
public class RestResponseEntityException         


        
相关标签:
3条回答
  • 2020-12-24 05:29

    Springs ResponseEntityExceptionHandler has a method handleException which is annotated with :

    @ExceptionHandler({     
            ...
            MethodArgumentNotValidException.class,
            ... 
        })
    

    Your method handleMethodArgumentNotValidException is also annotated to handle MethodArgumentNotValidException. So spring finds two methods that should be used to handle the same exception, that is the reason for the exception.

    **Solution ** Do not add a new method handleMethodArgumentNotValidException instead just override the method ResponseEntityExceptionHandler.handleMethodArgumentNotValid , and do not annotate it. Your class ErrorWrapper must extend ResponseEntity for that.

    0 讨论(0)
  • 2020-12-24 05:30

    Handel Exception

    @ControllerAdvice
    @RestController
    @Slf4j
    public class ExceptionHandler extends ResponseEntityExceptionHandler {
        @Override
        protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
            List<String> errorList = ex
                    .getBindingResult()
                    .getFieldErrors()
                    .stream()
                    .map(fieldError -> fieldError.getDefaultMessage())
                    .collect(Collectors.toList());
            ErrorDetails errorDetails = new ErrorDetails(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errorList);
            return handleExceptionInternal(ex, errorDetails, headers, errorDetails.getStatus(), request);
        }
    }
            }
    

    Customize Error Message

    @Data
    public class ErrorDetails {
        private HttpStatus status;
        private String message;
        private List<String> errors;
    
        public ErrorDetails(HttpStatus status, String message, List<String> errors) {
            super();
            this.status = status;
            this.message = message;
            this.errors = errors;
        }
    
        public ErrorDetails(HttpStatus status, String message, String error) {
            super();
            this.status = status;
            this.message = message;
            errors = Arrays.asList(error);
        }
    }
    

    Sample Response

      {
          "status": "BAD_REQUEST",
          "message": "Validation failed for argument [0] in public void com.ns.hospitalmanagement.resource.PatientResource.createPatient(com.ns.hospitalmanagement.entity.Patient) with 2 errors: [Field error in object 'patient' on field 'name': rejected value [null]; codes [NotNull.patient.name,NotNull.name,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [patient.name,name]; arguments []; default message [name]]; default message [Name Can not be Null]] [Field error in object 'patient' on field 'name': rejected value [null]; codes [NotEmpty.patient.name,NotEmpty.name,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [patient.name,name]; arguments []; default message [name]]; default message [Name Can not be Empty]] ",
          "errors": [
            "Name Can not be Null",
            "Name Can not be Empty"
          ]
        }
    
    0 讨论(0)
  • 2020-12-24 05:40

    Try to override the method handleMethodArgumentNotValid, In my case the method become like this:

      @Override
      protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                    HttpHeaders headers, HttpStatus status,
                                                                    WebRequest request) {
        String errorMessage = ex.getBindingResult().getFieldErrors().stream()
                     .map(DefaultMessageSourceResolvable::getDefaultMessage)
                     .findFirst()
                     .orElse(ex.getMessage());
        return response(ex, request, HttpStatus.BAD_REQUEST, errorMessage);
      }
    
      private ResponseEntity<Object> response(Exception ex, WebRequest request, HttpStatus status,
                                              String message) {
        return handleExceptionInternal(ex, message, header(), status, request);
      }
    
    0 讨论(0)
提交回复
热议问题