从文件系统提供静态资源| Spring Boot Web

时间:2015-02-17 06:54:48

标签: spring-mvc spring-boot

使用Spring Boot Web应用程序我尝试从项目外部的文件系统文件夹中提供静态资源。

文件夹结构如下: -

          src
             main
                 java
                 resources
             test
                 java
                 resources
          pom.xml
          ext-resources   (I want to keep my static resources here)
                 test.js

弹簧配置: -

@SpringBootApplication
public class DemoStaticresourceApplication extends WebMvcConfigurerAdapter {

    public static void main(String[] args) {
        SpringApplication.run(DemoStaticresourceApplication.class, args);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/test/**").addResourceLocations("file:///./ext-resources/")
                .setCachePeriod(0);
    }
}

在我的浏览器中点击“http://localhost:9999/test/test.js”会返回404。

如何配置ResourceHandlerRegistry以提供上述'ext-resources'文件夹中的静态资源?

我应该能够为dev / prod环境打开/关闭缓存。

由于

更新1

提供绝对文件路径: -

@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/test/**")
                .addResourceLocations(
                        "file:///C:/Sambhav/Installations/workspace/demo-staticresource/ext-resources/")
                .setCachePeriod(0);
}

我如何提供相对位置?绝对的道路将使我的生活在建设和生活中变得艰难部署过程。

3 个答案:

答案 0 :(得分:24)

file:///是指向文件系统根目录的绝对URL,因此file:///./ext-resources/表示Spring Boot正在根目录中名为ext-resources的目录中查找资源。 / p>

更新您的配置,使用file:ext-resources/之类的内容作为网址。

答案 1 :(得分:1)

Spring Boot Maven插件可以为类路径添加额外的目录。在你的情况下,你可以把它包含在你的pom中。

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>${spring.boot.version}</version>
    <configuration>
        <folders>
            <folder>${project.build.directory}/../ext-resources</folder>
        </folders>

        ...
    </configuration>
</plugin>

因此,您不需要在课程中包含任何硬编码。只需使用

启动您的webapp即可
mvn spring-boot:run

答案 2 :(得分:0)

在我们的案例中,Spring Boot 2提供的所有解决方案均不起作用,WebMvcConfigurerAdapterWebMvcConfigurer都不适用。使用@EnableWebMvc注释使情况变得更糟,因为在我想的时候,WebMvcAutoConfiguration当时被忽略了,因此正常的内容在停止工作之前就可以正常工作了。

一种可能的解决方案是定义spring.resources.static-locations属性,但这意味着静态位置是硬编码的。我们想在运行时添加一个静态位置,以便它与我们要部署的环境无关,因为包含资源的外部目录位于与部署应用程序相同的位置。为此,我提出了以下解决方案:

@Configuration
@SpringBootApplication
public class MainConfiguration {
    @Inject
    public void appendExternalReportingLocation(ResourceProperties resourceProperties) {
        String location = "file://" + new File("ext-resources").getAbsolutePath();
        List<String> staticLocations = newArrayList(resourceProperties.getStaticLocations());
        staticLocations.add(location);
        resourceProperties.setStaticLocations(staticLocations.toArray(new String[staticLocations.size()]));
    }
}

更新:不幸的是,上述解决方案仅在从IDE(例如IntelliJ)中启动Spring Boot应用程序时有效。因此,我想出了另一种解决方案,可以从文件系统提供静态内容。

首先,我创建了一个过滤器,如下所示:

public class StaticContentFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        File file = new File(new File("ext-resources").getAbsolutePath(), ((HttpServletRequest)request).getServletPath());
        if (file.exists() && !file.isDirectory()) {
            org.apache.commons.io.IOUtils.copy(new FileInputStream(file), response.getOutputStream());
        }
        else {
            chain.doFilter(request, response);
        }
    }
}

然后我在Spring Boot中注册如下:

@Configuration
@SpringBootApplication
public class MainConfiguration {
    @Bean
    public FilterRegistrationBean staticContentFilter() {
        return new FilterRegistrationBean(new StaticContentFilter());
    }
}