zeo*_*dtr 28 spring tomcat spring-boot
Spring Boot的嵌入式tomcat非常方便,适用于开发和部署.
但是如果应该添加另一个(第三方)WAR文件(例如,GeoServer)呢?
也许以下是正常程序:
但如果可以进行以下配置,那就太好了.
怎么做到呢?
UPDATE
当spring引导应用程序由胖jar(=可执行jar)构成时,答案中的代码是不够的.修订后的内容如下:
@Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
    return new TomcatEmbeddedServletContainerFactory() {
        @Override
        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                Tomcat tomcat) {
            try {
                Context context = tomcat.addWebapp("/foo", "/path/to/foo.war");
                WebappLoader loader =
                    new WebappLoader(Thread.currentThread().getContextClassLoader());
                context.setLoader(loader);
            } catch (ServletException ex) {
                throw new IllegalStateException("Failed to add webapp", ex);
            }
            return super.getTomcatEmbeddedServletContainer(tomcat);
        }
    };
}
由于系统类加载器无法加载胖jar中的jar文件,因此必须指定显式父类加载器.否则,附加WAR无法将库jar加载到添加了WAR的spring boot应用程序的fat jar中.
And*_*son 26
您可以使用添加war文件到嵌入式Tomcat Tomcat.addWebapp.正如其javadoc所说,它"相当于向Tomcat的web应用程序目录添加Web应用程序".要在Spring Boot中使用此API,您需要使用自定义TomcatEmbeddedServletContainerFactory子类:
@Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
    return new TomcatEmbeddedServletContainerFactory() {
        @Override
        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                Tomcat tomcat) {
            // Ensure that the webapps directory exists
            new File(tomcat.getServer().getCatalinaBase(), "webapps").mkdirs();
            try {
                Context context = tomcat.addWebapp("/foo", "/path/to/foo.war");
                // Allow the webapp to load classes from your fat jar
                context.setParentClassLoader(getClass().getClassLoader());
            } catch (ServletException ex) {
                throw new IllegalStateException("Failed to add webapp", ex);
            }
            return super.getTomcatEmbeddedServletContainer(tomcat);
        }
    };
}
接受的答案涵盖 Spring Boot 1.x。提到的类不再出现在 Spring Boot 2.x 中。使用版本 2 时,您需要使用不同的版本:
    @Bean
    @ConditionalOnProperty(name = "external.war.file")
    public TomcatServletWebServerFactory servletContainerFactory(@Value("${external.war.file}") String path,
                                                                 @Value("${external.war.context:}") String contextPath) {
        return new TomcatServletWebServerFactory() {
            @Override
            protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
                new File(tomcat.getServer().getCatalinaBase(), "webapps").mkdirs();
                Context context = tomcat.addWebapp(contextPath, path);
                context.setParentClassLoader(getClass().getClassLoader());
                return super.getTomcatWebServer(tomcat);
            }
        };
    }
此外,Spring Boot 嵌入式 Tomcat 默认不包含 JSP 的依赖项。如果您在外部战争中使用 JSP,则需要包含它们。
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>
更新:我写了一篇更详细的博客文章,介绍如何为 Spring Boot 1 和 2 进行设置。
| 归档时间: | 
 | 
| 查看次数: | 13129 次 | 
| 最近记录: |