Niedawno zaimplementowałem Spring Security w mojej aplikacji Spring 4/Hibernate Web do obsługi logowania/wylogowywania i różnych ról użytkowników.Jak sprawnie obsługiwać wyjątki w Spring Security, które nie są obsługiwane przez ControllerAdvice?
Po wielu lekturze wygląda na to, że działa całkiem dobrze, ale zauważyłem, że wyjątki generowane z powodu niewłaściwej konfiguracji Spring Security nie były obsługiwane z wdzięcznością za pomocą mojego niestandardowego programu obsługi, ale pokazywane jako brzydka strona błędu Tomcat (pokazująca stan HTTP 500 - Wymagana jest usługa UserDetailsService, a następnie ślad stosu).
Rozwiązywanie dany błąd nie było trudne (dodawanie userDetailsService (userDetailsService) w konfiguracji Twój na zawsze), ale pozostaje faktem, że pewne wyjątki rzucane nie są obsługiwane przez ControllerAdvice poniżej obsługi MaxUploadSizeExceededException i wszystkie inne wyjątki środowiska wykonawczego:
@ControllerAdvice
public class ExceptionHandlingControllerAdvice {
public static final String DEFAULT_ERROR_VIEW = "genericerror";
@ExceptionHandler(value = MaxUploadSizeExceededException.class)
public View maxUploadSizeExceededExceptionHandler(
HttpServletRequest req) throws IOException {
String redirectUrl = req.getRequestURL().toString();
RedirectView rv = new RedirectView(redirectUrl);
FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(req);
if (outputFlashMap != null) {
outputFlashMap.put(KeyConstants.FLASH_ERROR_KEY, "Bestand is te groot");
}
return rv;
}
@ExceptionHandler(value = RuntimeException.class)
public View defaultErrorHandler(HttpServletRequest req, Exception e) {
RedirectView rv = new RedirectView("/error", true); //context relative
StackTraceElement[] steArray = e.getStackTrace();
StringBuilder stackTrace = new StringBuilder();
for (StackTraceElement element: steArray) {
stackTrace.append(element.toString() + "\n");
}
FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(req);
if (outputFlashMap != null) {
outputFlashMap.put("url", req.getRequestURL());
outputFlashMap.put("excClassName", e.getClass().getName());
outputFlashMap.put("excMessage", e.getMessage());
outputFlashMap.put("excStacktrace", stackTrace.toString());
}
e.printStackTrace();
return rv;
}
}
Ale wyjątek zgłoszony przez nieskompletowane skonfigurowane zabezpieczenia prawdopodobnie nie jest przechwytywany przez ten mechanizm, ponieważ żądanie POST logowania jest przechwytywane przez Spring Security przed wywołaniem jakiejkolwiek metody kontrolera. Chciałbym pokazać WSZYSTKIE wyjątki w pełen wdzięku sposób na stronie błędów niestandardowych, również tych wyrzuconych przed uruchomieniem Kontrolera.
Nie mogę znaleźć wiele informacji na ten temat, wszystkie techniki obsługi błędów opisane w instrukcji Spring (http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-exceptionhandlers) wydają się korzystać z porady kontrolera.
Czy istnieje wygodny sposób obsługi WSZYSTKICH wyjątków w sposób ogólny? I sprawia, że moja klasa rada kontrolera do obsługi wyjątków jest zbędna?
Dlaczego nie można po prostu zmienić @ExceptionHandler (value = RuntimeException.class) na @ExceptionHandler (value = Exception.class). W ten sposób powinieneś być w stanie obsłużyć wszystkie wyjątki. – JChap
Nie, to nie rozwiązuje problemu. Problem nie polega na tym, że klasa wyjątków jest zbyt specyficzna, ale wyjątek jest generowany przed wywołaniem metody kontrolera i wchodzi w grę narzędzie ControllerAdvice. – klausch
Ok Gotcha, może być wtedy niski poziom jak przy użyciu obsługi wyjątku serwletu. – JChap