问题
I have written custom exception handler class for one of my spring controllers to validate if email attribute from request param is in the proper format. So created a new class which extends ResponseEntityExceptionHandler
class and wrote a method with @ExceptionHandler
.
But during spring boot application startup, I am getting below exception which is stopping to run my project. Could someone help me to resolve this?
Exception during server startup:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'handlerExceptionResolver' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerExceptionResolver]: Factory method 'handlerExceptionResolver' threw exception;
nested exception is java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException]: {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) throws java.lang.Exception}
Custom Class to handle 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;
}
}
回答1:
The ambiguity is because you have the same method - @ExceptionHandler in both the classes - ResponseEntityExceptionHandler, MethodArgumentNotValidException. You need to write the overridden method as follows to get around this issue -
@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);
}
回答2:
The problem you experience here is to be expected. You're effectively extending Spring ResponseEntityExceptionHandler
which by default already contains a declaration for MethodArgumentNotValidException
in it's own @ExceptionHandler
annotation.
You can easily check on this from the source of the class:
https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java
This is why you see this bit of error in the logs:
java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException]
Based on all the above you should remove your own exception handler method and override the ones from it.
回答3:
Spring has a built in ResponseEntityExceptionHandler
for MethodArgumentNotValidException
. So you have two handlers for the same exception which is not allowed.
You can try to override ResponseEntityExceptionHandler.handleMethodArgumentNotValid()
.
来源:https://stackoverflow.com/questions/51991992/getting-ambiguous-exceptionhandler-method-mapped-for-methodargumentnotvalidexce