Spring 启动 : How to add another WAR files to the embedded tomcat?

标签 spring tomcat spring-boot

Spring Boot 的嵌入式 tomcat 非常方便,无论是开发还是部署。

但是如果应该添加另一个(第 3 方)WAR 文件(例如 GeoServer)怎么办?

也许以下是正常的程序:

  1. 安装一个普通的 Tomcat 服务器。
  2. 将 Spring Boot 应用程序构建为 WAR 文件,并将其添加到 Tomcat 的 webapps 文件夹中。
  3. 还将另一个(第 3 方)WAR 文件添加到 webapps 文件夹。

但如果可以进行以下配置就好了。

  1. 将 Spring 引导应用程序构建为独立的 Jar,其中包括嵌入式 Tomcat。
  2. 部署 Spring Boot 应用程序 Jar。
  3. 将另一个(第 3 方)WAR 文件添加到嵌入式 Tomcat 可识别的文件夹中。
  4. 使用嵌入式 Tomcat 提供 Spring Boot 应用程序内容和另一个 WAR 的内容。

怎么做?

更新

spring boot应用用fat jar(=executable 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);
        }

    };
}

由于系统类加载器无法加载 fat jar 中的 jar 文件,因此必须指定显式父类加载器。否则,附加的 WAR 无法加载添加了 WAR 的 spring boot 应用的 fat jar 中的库 jar。

最佳答案

您可以使用Tomcat.addWebapp 将war 文件添加到嵌入式Tomcat。正如其 javadoc 所说,它“相当于将 Web 应用程序添加到 Tomcat 的 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 启动 : How to add another WAR files to the embedded tomcat?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31374726/

相关文章:

java - OAuth2 Spring boot 缺少必需的“用户名

java - 独立 Tomcat 中的 Spring Boot 会忽略 DeferredResults 中设置的异常

mysql - 无法让 DataImportHandler 在 Tomcat 中为 Solr 工作

java - 甲骨文 ADF : ADFC-10001: cannot instantiate class 'com.wip.view.backing.Index'

spring-boot-starter 与 spring-boot-starter-xxx

java - 如何在 java 类中创建 Spring Security 3.1 数据源 bean

java - 我有 2 个服务类,它们都使用 Autowiring 的 bean 扩展同一个父类,我可以在一个类中使用 bean,但不能在另一个类中使用

java - 表单提交thymeleaf和Spring boot后如何保持在同一页面?

spring - 在 Spring Boot 中使用嵌入式 MongoDB 测试 @Transactional

java - Google 日历 API Java 403