Подтвердить что ты не робот

Как изящно обрабатывать исключения в Spring Безопасность не обрабатывается ControllerAdvice?

Недавно я реализовал Spring Security в моем веб-приложении Spring 4/Hibernate для обработки входа/выхода в систему и разных ролей пользователей.

После многого чтения, похоже, он работает довольно хорошо сейчас, но я заметил, что исключения, вызванные неправильной конфигурацией безопасности Spring, не были обработаны изящно с использованием моего настраиваемого обработчика, но показаны как уродливая страница ошибок Tomcat (показывающая HTTP Состояние 500 - UserDetailsService требуется, а затем stacktrace).

Решение конкретной ошибки было затруднительным (добавление userDetailsService (userDetailsService) в конфигурации RememberMe), но факт остается фактом: некоторые исключения, которые были выбраны, не обрабатываются ControllerAdvice показано ниже при обработке MaxUploadSizeExceededException и всех других исключений во время выполнения:

@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;
}
}

Но исключение, созданное незавершенной сконфигурированной безопасностью, вероятно, не улавливается этим механизмом, потому что запрос POST входа перехватывается Spring Security перед вызовом любого метода контроллера. Я хотел бы показать ВСЕ исключения изящным способом на странице пользовательской ошибки, а также те, которые были брошены до того, как контроллер встанет на свои места.

Я не могу найти много информации об этом, все методы обработки ошибок, описанные в руководстве Spring (http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-exceptionhandlers), похоже, используют Консультация контроллера.

Существует ли удобный способ обработки ВСЕХ исключений общим способом? И делает ли мой советский класс рекомендаций обработкой исключений излишним?

4b9b3361

Ответ 1

Как вы заметили, @ExceptionHandler не работает для исключения, которое выбрано вне (ниже в куче, чем) Spring MVC.

Вы можете поймать все исключения, не обнаруженные в другом месте, указав страницу с ошибкой в ​​web.xml:

<error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/500</location>
</error-page>

Вы делаете эту страницу 500 как обычную страницу, обычно в Spring MVC:

@RequestMapping(value="/500")
public @ResponseBody String handleException(HttpServletRequest req) {

    // this will get the exception thrown/caught
    Throwable exception = (Throwable)req.getAttribute("javax.servlet.error.exception");

    // customize the response as you want
    return "Internal server error.";
}

Ответ 2

Если вы используете Spring Boot, вы можете создать настраиваемый ErrorController, по умолчанию у вас есть имя BasicErrorController.