Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

spring-4

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

@ControllerAdvice public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {      private Logger log = LoggerFactory.getLogger(RestResponseEntityExceptionHandler.class);      @Autowired     private ApplicationContext applicationContext;      @ExceptionHandler({ ConstraintViolationException.class })     @ResponseStatus(HttpStatus.BAD_REQUEST)     @ResponseBody     public ErrorWrapper handleConstraintViolationException(ConstraintViolationException e) {         String fieldName = e.getConstraintName();         String message = getResourceMessage(fieldName + ".alreadyExists", "Already Exists");         return new ErrorWrapper(fieldName + ".error", message);     }      @ExceptionHandler({ MethodArgumentNotValidException.class })     @ResponseStatus(HttpStatus.BAD_REQUEST)     @ResponseBody     public ErrorWrapper handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {         return new ErrorWrapper(".error", "test");     }      private String getResourceMessage(String key, String defaultMessage) {         String message = applicationContext.getMessage(key, null, Locale.getDefault());         if (StringUtils.isNotEmpty(message)) {             return message;         }         return defaultMessage;     } } 

I'm getting following Exception

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException]: {public com.ca.bean.ErrorWrapper com.ca.exceptionHandler.RestResponseEntityExceptionHandler.handleMethodArgumentNotValidException(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)}     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) ~[spring-context-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) ~[spring-context-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444) ~[spring-web-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326) ~[spring-web-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) [spring-web-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5099) [catalina.jar:7.0.70]     at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5615) [catalina.jar:7.0.70]     at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) [catalina.jar:7.0.70]     at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1571) [catalina.jar:7.0.70]     at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1561) [catalina.jar:7.0.70]     at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_92]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_92]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_92]     at java.lang.Thread.run(Thread.java:745) [na:1.8.0_92] Caused by: java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException]: {public com.ca.bean.ErrorWrapper com.ca.exceptionHandler.RestResponseEntityExceptionHandler.handleMethodArgumentNotValidException(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)}     at org.springframework.web.method.annotation.ExceptionHandlerMethodResolver.addExceptionMapping(ExceptionHandlerMethodResolver.java:109) ~[spring-web-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.web.method.annotation.ExceptionHandlerMethodResolver.<init>(ExceptionHandlerMethodResolver.java:76) ~[spring-web-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.initExceptionHandlerAdviceCache(ExceptionHandlerExceptionResolver.java:265) ~[spring-webmvc-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.afterPropertiesSet(ExceptionHandlerExceptionResolver.java:241) ~[spring-webmvc-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.3.0.RELEASE.jar:4.3.0.RELEASE]     ... 21 common frames omitted 

I'm using spring 4.3.0. I want to handle MethodArgumentNotValidException and want to send custom message. What mistake I'm doing? Please help.

like image 502
Krishna Avatar asked Jul 09 '16 13:07

Krishna


2 Answers

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.

like image 102
Stefan Isele - prefabware.com Avatar answered Sep 29 '22 04:09

Stefan Isele - prefabware.com


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);   } 
like image 43
Dayan Costa Avatar answered Sep 29 '22 04:09

Dayan Costa