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 boot 应用程序构建为独立的 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中的library 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/42052345/

相关文章:

mysql - Spring Boot从url给出的mysql表中获取数据

java - HandlerInterceptorAdapter 不起作用

mysql - 表名变为大写

java - 如何删除tomcat中加载的Jar文件?

css - 从 Tomcat 到 Glassfish 的类似 css 文件夹路径

java - 同一方法上的@PutMapping 和@PostMapping 注释

java - 将基于配置文件的属性文件解析为 Spring 测试

java - @ControllerAdvice不处理异常

http - Tomcat、HTTP、选项

java - Spring MVC 填充 @RequestParam Map<String, String>