Какой самый простой способ перейти от регистрации исключений к обработке исключений в приложении Spring MVC? - PullRequest
8 голосов
/ 03 июля 2011

В приложении My Spring MVC полно методов, которые выглядят следующим образом:

@RequestMapping(value = "/foo", method = RequestMethod.GET)
public final void foo(HttpServletRequest request, ModelMap modelMap){
    try{
        this.fooService.foo();
    }
    catch (Exception e){
        log.warn(e.getMessage(), e);
    }
}

Исключения перехватываются и регистрируются, но не обрабатываются иначе.

Вызванный выше fooService делает то же самоевещь, никогда не выбрасывать исключения в контроллер, а перехватывать и регистрировать их.Итак, на самом деле этот код исключения контроллера никогда не будет вызван.

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

1 Ответ

9 голосов
/ 04 июля 2011

Избавьтесь от всех catch утверждений, если все, что они делают - это небрежное ведение журнала. catch предназначен для обработки ошибки, а не для ее скрытия.

Как только все эти защелки удалены, установите один глобальный обработчик исключений в Spring MVC ( 1 , 2 , 3 , ...). Просто реализуйте это тривиальный интерфейс:

public interface HandlerExceptionResolver {
    ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
}

В вашем средстве разрешения исключений вы можете просто зарегистрировать исключение один раз и отпустить его как необработанное (вернуть null), чтобы сопоставления ошибок в web.xml перенаправили запрос на соответствующую страницу ошибки. Или вы можете обработать исключение самостоятельно и отобразить страницу с ошибкой. AFAIK, в простейшем случае не требуется преобразователь исключений из регистра, просто определите его как Spring bean / annotate с @Service.

Помните, что ловить исключение можно только тогда, когда вы знаете, что делать. Ведение журнала только для устранения неполадок, оно ничего не обрабатывает.

Кстати это:

log.warn(e.getMessage(), e);

- это не только очень плохая обработка исключений, но и немного неправильная. Если в вашем исключении нет сообщения, вы увидите загадочный null непосредственно перед трассировкой стека. Если это произойдет, сообщение появится дважды (протестировано с Logback):

22:51:23.985 WARN [main][Foo] OMG! - this is the exception message
java.lang.IllegalStateException: OMG! - this is the exception message
    at Foo.bar(Foo.java:20) ~[test-classes/:na]

... иногда нежелательно, особенно когда сообщение об исключении очень длинное.


ОБНОВЛЕНИЕ : При написании собственного регистратора исключений рассмотрите возможность реализации org.springframework.web.servlet.HandlerExceptionResolver и org.springframework.core.Ordered. getOrder() должен возвращать что-то маленькое (например, 0), чтобы ваш обработчик имел приоритет над встроенными обработчиками.

Просто со мной случилось, что org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver, запущенный до того, как мой обработчик возвратил HTTP 500 без регистрации исключения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...