当前位置: 首页 > 知识库问答 >
问题:

如何优雅地处理Spring Security中未由ControllerAdvice处理的异常?

薛俊美
2023-03-14

我最近在我的Spring4/Hibernate Web应用程序中实现了Spring Security来处理登录/退出和不同的用户角色。

经过大量阅读,它现在似乎工作得很好,但我注意到,由于错误的Spring Security配置而引发的异常没有使用我的自定义处理程序进行优雅的处理,而是显示为一个丑陋的Tomcat错误页面(显示HTTP状态500-UserDetailsService是必需的,后跟一个stacktrace)。

解决特定错误并不困难(在RememberMe配置中添加userDetailsService(userDetailsService)),但事实仍然是,以下处理MaxUploadSizeExceptedException和所有其他运行时异常的ControllerAdvice未处理引发的某些异常:

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

但是不完全配置的安全性引发的异常可能不会被此机制捕获,因为在调用任何控制器方法之前,Spring Security会拦截登录POST请求。我想在自定义错误页面上以优雅的方式显示所有异常,也是在控制器到位之前抛出的异常。

关于这一点,我找不到太多的信息,在Spring手册(http://docs.Spring.io/Spring/docs/current/spring-framework-reference/htmlsingle/#mvc-exceptionhandlers)中描述的所有错误处理技术似乎都使用了控制器建议。

是否有一种方便的方法以泛型的方式处理所有异常?并使处理异常的控制器建议类变得多余?

共有1个答案

祁绪
2023-03-14

正如您所注意到的,@exceptionhandler对于在Spring MVC外部抛出(堆中比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.";
}
 类似资料:
  • 我已经浏览了所有相关的帖子,但是我的@Controlller建议似乎没有处理从Controller类抛出的自定义异常。但是@Controller类中的@ExceptionHandler确实处理了异常。我不知道是什么错误。 网状物xml: dispatcher servlet。xml: @控制器建议等级: @ControllerAdvice与控制器位于同一个包中。

  • 让我们假设我们有这样一个用python编写的琐碎守护进程: 我们使用< code>start-stop-daemon对其进行守护,默认情况下,它会在< code> - stop上发送< code > SIGTERM (< code > TERM )信号。 假设当前执行的步骤是。此时我们正在发送信号。 发生的情况是执行立即终止。 我发现我可以使用<code>signal.signal(signal.

  • 本文向大家介绍SpringBoot如何优雅地处理全局异常详解,包括了SpringBoot如何优雅地处理全局异常详解的使用技巧和注意事项,需要的朋友参考一下 前言 之前用springboot的时候,只知道捕获异常使用try{}catch,一个接口一个try{}catch,这也是大多数开发人员异常处理的常用方式,虽然屡试不爽,但会造成一个问题,就是一个Controller下面,满屏幕的try{}cat

  • 我正在使用Spring Boot 1.5.9开发我的应用程序。我需要实现jwt身份验证,我使用了jjwt库。以下代码来自我的自定义身份验证安全筛选器,它继承自。在这里,我试图从令牌解析用户名,当自动解析用户名时,jwt会验证用户名,并检查令牌的过期时间。我调试了它,它可以工作,所以接下来我想向客户端应用发送正确的消息,说明身份验证失败的原因。我想抛出一个ExpiredJwtException,并使

  • 问题内容: 假设我们有一个用python编写的琐碎守护程序: 我们将它守护起来,默认使用它发送信号–。 假设当前执行的步骤是。此时此刻,我们正在发送TERM信号。 发生的情况是执行立即终止。 我发现我可以使用处理信号事件,但事实是它仍然会中断当前执行并将控制权传递给。 因此,我的问题是-是否可以不中断当前执行,而是TERM在单独的线程(?)中处理信号,以便能够进行设置,从而有机会优雅地停止运行?

  • 本文向大家介绍Spring Boot优雅地处理404异常问题,包括了Spring Boot优雅地处理404异常问题的使用技巧和注意事项,需要的朋友参考一下 背景 在使用SpringBoot的过程中,你肯定遇到过404错误。比如下面的代码: 当我们使用错误的请求地址(POST http://127.0.0.1:8888/hello/test1?id=98)进行请求时,会报下面的错误: 虽然上面的返回