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

时间:2016-12-16 10:37:32

标签: spring-boot

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

当我在servlet容器上部署WAR时,这非常有用。但是当我将应用程序作为可执行WAR运行时,它不起作用,因为嵌入式servlet容器不扫描类路径META-INF / resources。

例如,对于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

1 个答案:

答案 0 :(得分: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