Ho recentemente implementato Spring Security nell'applicazione Web Spring 4/Hibernate per gestire l'accesso/uscita e diversi ruoli utente.Come gestire con garbo le eccezioni in Spring Security non gestite da ControllerAdvice?
Dopo molte letture sembra funzionare abbastanza bene ora, ma ho notato che le eccezioni lanciate a causa di una errata configurazione di Spring Security non sono state gestite correttamente usando il mio gestore personalizzato ma mostrate come una brutta pagina di errore di Tomcat (che mostra lo stato HTTP 500 - È richiesto UserDetailsService seguito da uno stacktrace).
Risolvendo l'errore particolare non era difficile (aggiungendo userDetailsService (userDetailsService) nella configurazione RememberMe), ma rimane il fatto che alcune eccezioni generate non sono gestiti dal ControllerAdvice mostrate sotto movimentazione MaxUploadSizeExceededException e tutte le altre eccezioni runtime:
@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;
}
}
Ma l'eccezione generata dalla Sicurezza configurata incompleta probabilmente non viene catturata da questo meccanismo perché la richiesta POST di accesso viene intercettata da Spring Security prima che venga chiamato qualsiasi metodo del controller. Vorrei mostrare TUTTE le eccezioni in modo aggraziato su una pagina di errore personalizzata, anche quelle lanciate prima che un Controller entri in posizione.
Non riesco a trovare molte informazioni al riguardo, tutte le tecniche di gestione degli errori descritte nel manuale Spring() sembrano utilizzare un consiglio del controller.
Esiste un modo conveniente per gestire TUTTE le eccezioni in modo generico? E rende superflua la mia classe di consigli Controller per gestire le eccezioni?
Perché non è possibile modificare semplicemente @ExceptionHandler (value = RuntimeException.class) in @ExceptionHandler (value = Exception.class). In questo modo dovresti essere in grado di gestire tutte le eccezioni. – JChap
No, questo non risolve il problema. Il problema non è che la classe di eccezione sia troppo specifica ma che l'eccezione venga lanciata prima che venga chiamato un metodo Controller e che ControllerAdvice entri in gioco. – klausch
Ok Gotcha, Potrebbe essere che tu vai a un livello basso come usare il gestore delle eccezioni del servlet. – JChap