修复 org.springframework.context.ApplicationContextException: Unable to start embedded container 报错问题

JAVA herman 54浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

SpringBoot 的这个错误很常见,也很简单,但也足以抵挡住不少新手学习者,让他们举步维艰。

最近有一个网友就私信我说,他的 SpringBoot 程序无法启动,报 org.springframework.context.ApplicationContextException: Unable to start embedded container 异常。

根据这个异常得知,是 SpringBoot 内嵌的容器无法启动了。至于具体的原因还得看详细日志了。一番沟通后,他把错误日志发给了我。

2019-11-09 08:49:59  [ main:28882 ] - [ ERROR ]  Application startup failed
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is java.lang.IllegalArgumentException: Error page location [xttblog/404.jsp] must start with a '/'
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
	at com.xttblog.MainApplication.main(MainApplication.java:60)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:67)
Caused by: java.lang.IllegalArgumentException: Error page location [xttblog/404.jsp] must start with a '/'
	at org.apache.catalina.core.StandardContext.addErrorPage(StandardContext.java:2930)
	at org.springframework.boot.context.embedded.tomcat.TomcatErrorPage.addToContext(TomcatErrorPage.java:83)
	at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.configureContext(TomcatEmbeddedServletContainerFactory.java:491)
	at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.prepareContext(TomcatEmbeddedServletContainerFactory.java:235)
	at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:178)
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164)
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134)

根据这个错误日志,我一眼就看出了原因。

简单来说,就是他使用了 org.springframework.boot.web.servlet.ErrorPage 定义了 404 的页面,让程序出现 404 后,跳转到自己定义的 404 页面上,而不是使用 nginx 或 tomcat、SpringBoot 等默认的 404 页面上。

由于 Spring Boot 默认使用嵌入式 Tomcat 容器,默认没有页面来处理 404 等常见错误。因此,为了给用户最佳的使用体验,404 等常见错误需要我们自定义页面来处理。

这时,Springboot 提供的 ErrorPage 这个类的作用就可以派上用场了。

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {

            ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/403.html");
            ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "xttblog/404.jsp");
            ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");

            container.addErrorPages(error401Page, error404Page, error500Page);
        }
    };
}

但是,需要注意的是 ErrorPage 的 path 参数,必须是以“/”开头的路径字符串。如果不是以“/”开头的就会报本文所说的这个异常。

ErrorPage 非常的强大,还可以定义根据异常来选择展示的页面。用好它,也可以给用户带来不少友好的体验感!

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号1:xmtxtt(5000人已满),微信号2:codedq(5000人已满),微信号3:xttblog(超2800)。备注:“xttblog”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » 修复 org.springframework.context.ApplicationContextException: Unable to start embedded container 报错问题