2016-07-09 4 views
11

Я пытаюсь справиться MethodArgumentNotValidException используя @ControllerAdvice, как код, указанный ниже:Неоднозначный метод @ExceptionHandler отображается для [класса org.springframework.web.bind.MethodArgumentNotValidException]

@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; 
    } 
} 

Я получаю следующее исключение

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 

Я использую весну 4.3.0. Я хочу обрабатывать MethodArgumentNotValidException и хочу отправить специальное сообщение. Какую ошибку я делаю? Пожалуйста помоги.

ответ

22

Спрингс ResponseEntityExceptionHandler имеет метод handleException который с аннотацией:

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

Ваш метод handleMethodArgumentNotValidException также аннотированный для обработки MethodArgumentNotValidException. Таким образом, весна находит два метода, которые должны использоваться для обработки одного и того же исключения, что и является причиной исключения.

** Решение ** Не добавляйте новый метод handleMethodArgumentNotValidException вместо этого просто переопределите метод ResponseEntityExceptionHandler.handleMethodArgumentNotValid и не комментируйте его. Ваш класс ErrorWrapper должен расширять ResponseEntity для этого.

+4

метод handleException является окончательным методом. Следовательно, мы не можем переопределить это. Но этот метод имеет экземпляр для проверки метода MethodArgumentNotValidException и вызова метода с именем handleMethodArgumentNotValid. Поэтому я попытался переопределить метод handleMethodArgumentNotValid, и он сработал. Большое спасибо. – Krishna

+0

@ Кришна можно показать, как вы это решили? – BigDong

+0

@BigDong ... Мне нужно увидеть код, который у меня сейчас нет. Ill проверить и дать код, но это займет 9-10 часов – Krishna

3

Попробуйте переопределить метод handleMethodArgumentNotValid, В моем случае метод стал так:

@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); 
    } 
Смежные вопросы