我无法让Spring-boot项目提供静态内容。

我在src/main/resources下放置了一个名为static的文件夹。其中有一个名为images的文件夹。当我将应用程序打包并运行时,它无法找到我放在该文件夹中的图像。

我试着把静态文件放在公共、资源和META-INF/资源中,但都不起作用。

如果我jar -tvf app.jar,我可以看到文件在jar的右边文件夹: /static/images/head.png为例,但调用:http://localhost:8080/images/head.png,我得到的是一个404

知道为什么弹簧靴找不到这个吗?(我使用1.1.4 BTW)


当前回答

在我的例子中,一些静态文件没有提供,比如.woff字体和一些图像。但是css和js工作得很好。

更新:让Spring Boot正确地服务于woff字体的一个更好的解决方案是配置这个答案中提到的资源过滤,例如(注意,你需要包括和排除):

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <excludes>
            <exclude>static/aui/fonts/**</exclude>
        </excludes>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>false</filtering>
        <includes>
            <include>static/aui/fonts/**</include>
        </includes>
    </resource>
</resources>

-----旧的解决方案(工作,但会破坏一些字体)-----

另一个解决方案是使用setUseSuffixPatternMatch(false)禁用后缀模式匹配

@Configuration
public class StaticResourceConfig implements WebMvcConfigurer {
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        // disable suffix matching to serve .woff, images, etc.
        configurer.setUseSuffixPatternMatch(false);
    }
}

致谢:@Abhiji确实给了我4分。方向对了!

其他回答

如果从IDE中启动应用程序时出现问题(即从Eclipse或IntelliJ Idea启动),并使用Maven,解决方案的关键在Spring-boot Getting Started文档中:

如果你正在使用Maven,执行: MVN包&& Java -jar target/gs-spring-boot-0.1.0.jar

其中重要的部分是添加要在应用程序实际启动之前运行的包目标。(想法:运行菜单,编辑配置…,添加,然后选择运行Maven目标,并在字段中指定包目标)

与spring-boot的状态不同,要让我的spring-boot jar提供内容: 我必须通过这个配置类添加专门注册我的src/main/resources/static内容:

@Configuration
public class StaticResourceConfiguration implements WebMvcConfigurer {

    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
            "classpath:/META-INF/resources/", "classpath:/resources/",
            "classpath:/static/", "classpath:/public/" };

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
            .addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
    }
}

在我的例子中,一些静态文件没有提供,比如.woff字体和一些图像。但是css和js工作得很好。

更新:让Spring Boot正确地服务于woff字体的一个更好的解决方案是配置这个答案中提到的资源过滤,例如(注意,你需要包括和排除):

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <excludes>
            <exclude>static/aui/fonts/**</exclude>
        </excludes>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>false</filtering>
        <includes>
            <include>static/aui/fonts/**</include>
        </includes>
    </resource>
</resources>

-----旧的解决方案(工作,但会破坏一些字体)-----

另一个解决方案是使用setUseSuffixPatternMatch(false)禁用后缀模式匹配

@Configuration
public class StaticResourceConfig implements WebMvcConfigurer {
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        // disable suffix matching to serve .woff, images, etc.
        configurer.setUseSuffixPatternMatch(false);
    }
}

致谢:@Abhiji确实给了我4分。方向对了!

供参考:我还注意到,如果我添加了一个糟糕的休息控制器,我可以搞砸一个完美工作的spring boot应用程序,并阻止它从静态文件夹中提供内容

 @RestController
public class BadController {
    @RequestMapping(method= RequestMethod.POST)
    public String someMethod(@RequestParam(value="date", required=false)String dateString, Model model){
        return "foo";
    }
}

在本例中,在将坏控制器添加到项目后,当浏览器请求静态文件夹中可用的文件时,错误响应是'405 Method Not Allowed'。

注意,在坏控制器示例中没有映射路径。

不是说过了一年多才让死人复活,但之前所有的答案都忽略了一些关键点:

@EnableWebMvc on your class will disable org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration. That's fine if you want complete control but otherwise, it's a problem. There's no need to write any code to add another location for static resources in addition to what is already provided. Looking at org.springframework.boot.autoconfigure.web.ResourceProperties from v1.3.0.RELEASE, I see a field staticLocations that can be configured in the application.properties. Here's a snippet from the source: /** * Locations of static resources. Defaults to classpath:[/META-INF/resources/, * /resources/, /static/, /public/] plus context:/ (the root of the servlet context). */ private String[] staticLocations = RESOURCE_LOCATIONS; As mentioned before, the request URL will be resolved relative to these locations. Thus src/main/resources/static/index.html will be served when the request URL is /index.html. The class that is responsible for resolving the path, as of Spring 4.1, is org.springframework.web.servlet.resource.PathResourceResolver. Suffix pattern matching is enabled by default which means for a request URL /index.html, Spring is going to look for handlers corresponding to /index.html. This is an issue if the intention is to serve static content. To disable that, extend WebMvcConfigurerAdapter (but don't use @EnableWebMvc) and override configurePathMatch as shown below: @Override public void configurePathMatch(PathMatchConfigurer configurer) { super.configurePathMatch(configurer); configurer.setUseSuffixPatternMatch(false); }

恕我直言,在代码中减少错误的唯一方法就是不要尽可能地编写代码。使用已经提供的东西,即使这需要一些研究,但回报是值得的。

2021年7月编辑:

WebMvcConfigurerAdapter自Spring 5以来已弃用。实现WebMvcConfigurer并使用@Configuration进行注释。