2011-07-03 23 views
8

My Wiosna MVC aplikacja jest pełen metod, które wyglądają tak:Jaki jest najprostszy sposób na przejście z rejestrowania wyjątków do obsługi wyjątków w aplikacji 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); 
    } 
} 

wyjątkami są wychwytywane i rejestrowane, ale nie traktowane inaczej.

Wymienione powyżej fooService robi to samo, nigdy nie wysyłając wyjątków do kontrolera, ale przechwytując je i rejestrując. Tak więc ten kod wyjątku kontrolera nigdy nie zostanie wywołany.

Jakie jest najlepsze i najprostsze podejście do wdrożenia właściwej obsługi wyjątków w mojej aplikacji?

Odpowiedz

9

Pozbądź się wszystkich stwierdzeń catch, jeśli wszystko, co robią, to niedbale rejestrowanie. catch służy do obsługi błędu, a nie do jego ukrywania.

Gdy wszystkie te zaczepy są usuwane, zainstalować jedną globalną resolverowi wyjątków w Spring MVC (1, 2, 3 ...) Wystarczy wdrożyć ten banalny interfejs:

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

W swojej rezolwerem wyjątku może po prostu zarejestruj wyjątek jeden raz i pozostaw go jako nieprzetworzony (return null), aby odwzorowania błędów w web.xml przesyłają żądanie do odpowiedniej strony błędu. Możesz też obsłużyć wyjątek i renderować stronę błędu. AFAIK w najprostszym przypadku nie ma potrzeby rejestrowania wyjątku dla rejestru, po prostu zdefiniuj go jako Spring bean/adnotate z @Service.

Pamiętaj, złap wyjątek tylko wtedy, gdy wiesz, co zrobić. Rejestrowanie służy tylko do rozwiązywania problemów, nie obsługuje niczego.

BTW to:

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

jest nie tylko bardzo słaba obsługa wyjątków, ale jest również nieco błędne. Jeśli Twój wyjątek nie zawiera wiadomości, przed śledzeniem stosu zobaczysz tajemniczy komunikat: null. Jeśli tak, wiadomość pojawi się dwukrotnie (testowane z 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] 

... czasami niepożądany, zwłaszcza gdy wiadomość Wyjątkiem jest bardzo długa.


UPDATE: Pisząc własny rejestrator wyjątek rozważyć zastosowanie zarówno org.springframework.web.servlet.HandlerExceptionResolver i org.springframework.core.Ordered. getOrder() powinien zwrócić coś małego (np. 0), aby twój program obsługi miał pierwszeństwo przed wbudowanymi procedurami obsługi.

Po prostu przydarzyło mi się, że org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver uruchomione przed moją obsługą zwróciło HTTP 500 bez logowania wyjątku.

+0

Dziękuję. To jest świetne! – Peachy

Powiązane problemy