为 Spring Boot 嵌入式 tomcat 添加战争

Posted

技术标签:

【中文标题】为 Spring Boot 嵌入式 tomcat 添加战争【英文标题】:Add war to spring boot embedded tomcat 【发布时间】:2019-09-30 12:35:55 【问题描述】:

我有一个 spring-boot 2.1.2.RELEASE 应用程序,它使用嵌入式 tomcat 网络服务器并通过它的 SDK 使用 OpenKM。

现在,我有一些使用 restassured lib 进行 REST 调用和验证响应结构的集成测试。我的想法是将OpenKM.war 集成到这个 wmbedded tomcat 中,并且能够运行此测试,而无需在某些不同的服务器上运行 openkm 应用程序。

这就是我如何让嵌入式 tomcat 读取和部署 openkm.war:

@Configuration
public class TomcatConfig 
    @Bean
    public ServletWebServerFactory servletContainer() 
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() 
            @Override
            protected void postProcessContext(Context context) 
                SecurityConstraint securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            

            @Override
            protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) 
                new File(tomcat.getServer().getCatalinaBase(), "webapp").mkdirs();
                try 
                    tomcat.addWebapp("/okm", new ClassPathResource("webapp/openkm.war").getFile().toString());
                 catch (Exception ex) 
                    throw new IllegalStateException("Failed to add okm", ex);
                
                return super.getTomcatWebServer(tomcat);
            
        ;

        tomcat.addAdditionalTomcatConnectors(redirectConnector());
        return tomcat;
    

    private Connector redirectConnector() 
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        connector.setPort(8080);
        connector.setSecure(false);
        connector.setRedirectPort(8443);
        return connector;
    

deploy 比在 openkm 附带的独立 tomcat 网络服务器上花费的时间更长,但它可以部署。

但是部署过程失败:

IOException parsing XML document from URL [file:/tmp/tomcat.2352216859213135410.8080/openkm.xml]; nested exception is java.io.FileNotFoundException: /tmp/tomcat.2352216859213135410.8080/openkm.xml (No such file or directory)

我在 openkm.war 文件旁边有这个文件(加上 server.xml、context.xml),但似乎嵌入式 tomcat 不知道它。

所有这些文件都位于src/main/resources/webapp

所以,我想知道我缺少什么配置部分,或者是否有其他更好的配置来实现我想要的?

【问题讨论】:

我之前遇到过 tmp dir 的问题,你可以尝试手动创建tmp dir 并运行你的服务器吗? 该目录存在。问题是该文件确实不存在,所以我认为tomcat不知道它以及如何处理它。 【参考方案1】:

你可以尝试做类似的事情;

StandardContext ctx = (StandardContext) tomcat.addWebapp("/okm", new ClassPathResource("webapp/openkm.war").getFile().toString());
WebResourceRoot resources = new StandardRoot(ctx);
resources.addPreResources(new DirResourceSet(resources, "target mount path",
        new File("src/main/resources/webapp").getAbsolutePath(), "/"));
ctx.setResources(resources);

这样您就可以在 tomcat 部署中将您的 src/main/resources/webapp/ 文件夹安装在 target mount path 上。虽然我不确定这条路?你可以试试"/",也许"/WEB-INF/"?我目前无法在本地进行测试,但我希望这会有所帮助。

如果您需要在tomcat的不同文件夹中使用不同的文件,您也可以使用FileResourceSet挂载单个文件。

【讨论】:

以上是关于为 Spring Boot 嵌入式 tomcat 添加战争的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Boot 中嵌入的 tomcat 进行远程调试或本地调试

如何更改现有 Spring Boot 应用程序中的嵌入式 tomcat 版本?

spring boot 嵌入式 tomcat 不以 jcifs smb 库开头

在 Spring Boot 上更改嵌入式 tomcat 版本

嵌入式 Tomcat 中带有 JSP 标签库的 Spring-Boot

Spring Boot嵌入式Tomcat能否访问定义的spring.tomcat.basedir的webapps文件夹