嵌入式 servlet 容器不处理 Spring Boot 中的 META-INF/资源

Posted

技术标签:

【中文标题】嵌入式 servlet 容器不处理 Spring Boot 中的 META-INF/资源【英文标题】:Embedded servlet container does not handle META-INF/resources in Spring Boot 【发布时间】:2017-05-02 03:17:41 【问题描述】:

我的 WAR 应用程序使用非 Spring 库(用于 JSF)。该库使用servletContext.getResource("page.html") 进行初始化。 page.html 在 WEB-INF/lib 的 JAR 中,打包为 META-INF/resources/page.html

当我在 servlet 容器上部署 WAR 时效果很好。但是当我将应用程序作为可执行 WAR 运行时,它不起作用,因为嵌入式 servlet 容器不扫描类路径 META-INF/资源。

例如不使用 Undertow 类路径资源管理器:

private ResourceManager getDocumentRootResourceManager() 
    File root = getCanonicalDocumentRoot();
    if (root.isDirectory()) 
        return new FileResourceManager(root, 0);
    
    if (root.isFile()) 
        return new JarResourceManager(root);
    
    return ResourceManager.EMPTY_RESOURCE_MANAGER;

https://github.com/spring-projects/spring-boot/blob/master/spring-boot/src/main/java/org/springframework/boot/context/embedded/undertow/UndertowEmbeddedServletContainerFactory.java#L466

提问时间:为什么嵌入式 servlet 容器会忽略 META-INF/resources?制作可执行的 Servlet 3.0 应用程序是个问题。

类似问题:

Embedded Tomcat, executable jar, ServletContext.getRealPath()

https://github.com/spring-projects/spring-boot/issues/4218

【问题讨论】:

我用过很多spring boot,之前还没有听说过可执行的war。我想知道这是如何支持的。 【参考方案1】:

我通过以下配置解决了我的问题:

@Bean
public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() 
    UndertowEmbeddedServletContainerFactory factory =
    new UndertowEmbeddedServletContainerFactory();
    factory.addDeploymentInfoCustomizers(new UndertowDeploymentInfoCustomizer() 

        @Override
        public void customize(DeploymentInfo deploymentInfo) 
            deploymentInfo.setResourceManager(
                new ClassPathResourceManager(deploymentInfo.getClassLoader(),
                     "META-INF/resources"));
    );
    return factory;

一般来说,我认为嵌入式 Web 容器的行为方式没有得到充分说明。如果嵌入式 Web 容器为应用程序提供了一些功能子集,Spring Boot 开发人员会很高兴,迁移现有应用程序的人希望嵌入式容器提供常规容器的所有功能。例如 ServletContainerInitializers 在嵌入中被忽略:https://github.com/spring-projects/spring-boot/issues/321

【讨论】:

以上是关于嵌入式 servlet 容器不处理 Spring Boot 中的 META-INF/资源的主要内容,如果未能解决你的问题,请参考以下文章

带有嵌入式 servlet 容器的 Spring 应用程序运行错误

Spring Boot中嵌入式Servlet容器的比较

Spring boot:无法启动嵌入式 Tomcat servlet 容器

Spring容器类型推断

SpringBoot 源码解析 ----- Spring Boot的核心能力 - 内置Servlet容器源码分析(Tomcat)

springboot 嵌入式Servlet容器自动配置原理和容器启动原理