下面是关于“SpringBoot之自定义启动异常堆栈信息打印方式”的完整攻略。
1. 概述
在 SpringBoot 中,我们经常遇到启动应用时发生异常的情况,而默认的异常信息打印方式并不友好,难以定位问题。因此,本文将介绍如何通过自定义异常处理器,实现启动异常堆栈信息的定制化打印。
2. 实现步骤
2.1 创建异常处理器类
首先,我们需要创建一个异常处理器类,用于处理启动异常时的情况。该类需要继承自 ErrorController
接口,并且要带有 @RestController
、@RequestMapping
和 @Order
注解。
@RestController
@RequestMapping("/error")
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomErrorController implements ErrorController {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomErrorController.class);
@RequestMapping
public String error(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
// 异常信息输出到日志中
LOGGER.error("Exception during startup", exception);
// 返回友好的异常提示信息
return "Sorry, the server encountered an error:" + statusCode;
}
@Override
public String getErrorPath() {
return "/error";
}
}
在这个类中,我们首先获取了异常的状态码和异常对象,然后将异常信息输出到日志中。最后,返回一个友好的提示信息。
2.2 注册异常处理器
接下来,我们需要将自定义的异常处理器注册到 SpringBoot 中。我们可以通过创建一个 Spring @Configuration
类,并在其中添加 EmbeddedServletContainerCustomizer
实例来实现。
@Configuration
public class CustomExceptionHandler {
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return container -> {
ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error");
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/error");
ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error");
container.addErrorPages(error401Page, error404Page, error500Page);
};
}
}
这里我们定义了三个错误页面:401、404 和 500。这里的 /error
是我们在前面定义的异常处理器的路由地址。
3. 示例说明
假设我们的 SpringBoot 项目启动时,发生了一个空指针异常,那么我们如何打印出友好的堆栈信息呢?
3.1 通过默认方式打印异常信息
首先,我们看看默认的异常信息打印方式:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.demo.controller.UserController required a bean of type 'com.example.demo.service.UserService' that could not be found.
Action:
Consider defining a bean of type 'com.example.demo.service.UserService' in your configuration.
从上面的信息中可以看出,在构造 UserController 时,缺少了 UserService 类型的 Bean 对象。但是这个默认信息并不能更好地帮助我们找到问题的根源。
3.2 通过自定义方式打印异常信息
接下来,我们使用自定义异常处理器,看看对比效果如何。
我们启动项目后,可以在控制台中看到如下日志:
2022-02-22 10:10:10.123 ERROR CustomErrorController:24 - Exception during startup
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2022-02-22 10:10:10.123 WARN SpringApplication:558 - Error handling failed (ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@c0ac64f): org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.demo.controller.UserController required a bean of type 'com.example.demo.service.UserService' that could not be found.
Action:
Consider defining a bean of type 'com.example.demo.service.UserService' in your configuration.
可以看出,在自定义的异常处理器中,我们成功地输出了出错的具体堆栈信息。通过这些信息,我们可以更快地定位和解决问题。
4. 总结
通过本文的介绍,我们可以看到,自定义异常处理器可以帮助我们更好地定位、捕获和处理启动异常。在实际项目开发中,建议使用自定义异常处理器,提高项目的可靠性和稳定性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot之自定义启动异常堆栈信息打印方式 - Python技术站