Spring MVC @ExceptionHandler метод в контроллере никогда не вызывается

У меня есть контроллер Spring MVC с некоторыми простыми запросами службы REST. Я хотел бы добавить некоторую обработку ошибок, когда определенные исключения будут выбрасываться из моих сервисов, но я не могу получить метод обработчика, аннотированный с помощью @ExceptionHandler, на самом деле когда-либо вызываемый. Вот одна услуга, я намеренно бросаю исключение, чтобы попытаться применить метод моего обработчика. Метод обработчика никогда не вызывается, а Spring просто возвращает ошибку 500 вызывающему клиенту. У вас есть идеи о том, что я делаю неправильно?

@ExceptionHandler(IOException.class)
public ModelAndView handleIOException(IOException ex, HttpServletRequest request, HttpServletResponse response) {
    response.sendError(HttpServletResponse.SC_FORBIDDEN);
    System.out.println("It worked!");
    return new ModelAndView();
}

@RequestMapping(value = "/json/remove-service/{id}", method = RequestMethod.DELETE)
public void remove(@PathVariable("id") Long id) throws IOException {
    throw new IOException("The handler should take over from here!");
}

Ответы

Ответ 1

Этот совет на форуме Spring может помочь вам.

Вероятно, вы настроили beans для своего DispatchServlet в файле webmvc-servlet.xml(файл * -servlet.xml может быть назван по-разному)

Если XML файл уже включает в себя другой ExceptionResolver (например, SimpleMappingExceptionResovler Spring не будет автоматически добавлять какие-либо другие резольверы для вас. Таким образом, вручную добавление распознавателя аннотации следующим образом:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver" />

Должна включить обработку @HandlerException.

Ответ 2

Разочаровательно, я тоже страдал от этого. Я обнаружил, что если вы ошибочно реализуете Throwable вместо Exception, то распознаватель исключений просто перевернет ваш Throwable как IllegalStateException. Это не вызовет ваш @ExceptionHandler.

Если вы внедрили Throwable вместо Exception, попробуйте заменить его на Exception.

Здесь приведенный код от InvocableHandlerMethod

catch (InvocationTargetException e) {
            // Unwrap for HandlerExceptionResolvers ...
            Throwable targetException = e.getTargetException();
            if (targetException instanceof RuntimeException) {
                throw (RuntimeException) targetException;
            }
            else if (targetException instanceof Error) {
                throw (Error) targetException;
            }
            else if (targetException instanceof Exception) {
                throw (Exception) targetException;
            }
            else {
                String msg = getInvocationErrorMessage("Failed to invoke controller method", args);
                throw new IllegalStateException(msg, targetException);
            }
        }

Ответ 3

Я обнаружил, что @ExceptionHandler работает с Throwable, когда вы определяете метод таким образом:

@ExceptionHandler(Throwable.class)
@ResponseBody
public String handleException(Throwable e) {

}

В этом случае метод имеет только один аргумент типа Throwable. Если я попытаюсь использовать в этом методе некоторые дополнительные параметры (я пытался использовать модель), я получаю исключение 500 (этот метод не является вызовом). Однако это все еще работает, когда дополнительными параметрами являются HttpServlerRequest или HttpServlerResponse.

Ответ 4

Это не сработает, потому что когда вы возвращаете String, вы возвращаете View name.

Теперь ваш контроллер Spring MVC ищет этот метод никогда не вызывается! Почему нет?! просматривать и находить.

Убедитесь, что @ExceptionHandler сопоставлен с существующим представлением.