30

Spring最近关于在 Spring Boot 项目中使用静态 Web 内容的博客文章 ( https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot ) 表明可以使用几个资源目录:

  • /META-INF/资源/
  • /资源/
  • /静止的/
  • /上市/

这要归功于 WebMvcAutoConfiguration 类,它自动将这些目录添加到类路径中。这一切似乎都很好,并且在使用spring-boot-maven-plugin spring-boot:run目标时似乎工作,所有静态内容都在工作(例如:/index.html)。

当您打包 Spring Boot 项目并允许spring-boot-maven-plugin创建增强的 JAR 然后尝试使用您的静态内容运行您的项目时,java -jar my-spring-boot-project.jar您会发现您的静态内容现在返回 404 错误。

4

8 回答 8

43

事实证明,虽然 Spring Boot 很聪明地将各种资源目录添加到类路径中,但 Maven 不是,这取决于你来处理这部分。默认情况下,只会src/main/resources包含在您的 JAR 中。如果您/static在项目的根目录中创建一个名为的文件夹(如博客文章所暗示的那样),那么它在使用spring-boot:run Maven 目标时会正常工作,但在创建 JAR 后就不行了。

最简单的解决方案是在里面创建你的/static文件夹/src/main/resources,然后 Maven 会将它包含在 JAR 中。或者,您可以向 Maven 项目添加其他资源位置:

<resources>
    <resource>
        <directory>src/main/resources</directory>
    </resource>
    <resource>
        <directory>static</directory>
        <targetPath>static</targetPath>
    </resource>
</resources>

我希望这对某人有用,当你退后一步看看 Maven 是如何工作的时候,这很明显,但它可能会让一些使用 Spring Boot 的人感到困惑,因为它的设计几乎不需要配置。

于 2014-01-26T01:14:02.060 回答
8

我正用头撞墙,试图弄清楚如何用 gradle 做到这一点。有小费吗?

编辑:我通过将它添加到我的 build.gradle 来让它工作:

// Copy resources into the jar as static content, where Spring expects it.
jar.into('static') {
    from('src/main/webapp')
}
于 2014-03-18T05:42:15.383 回答
3

我浏览了几页来了解如何在 Spring 引导环境中提供静态内容。大多数建议都是围绕将静态文件放在 /static /resources/ src/main/webapp 等中。考虑共享以下方法。

  1. 允许 spring boot 自动配置 Dispatcher Servlet - 确保 DispatcherServletAutoConfiguration 不在 AutoConfiguration 的排除范围内。

    @EnableAutoConfiguration(exclude = { //DispatcherServletAutoConfiguration.class, })

  2. 注入您的外部目录以进行静态内容路由

    @Value("${static-content.locations:file:C:/myprj/static/") private String[] staticContentLocations;

3.Override WebMvcAutoConfiguration using WebMvcConfigurerAdapter 建议spring不要使用默认资源位置,而是使用我们指示它的内容。如下所示

@Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter()
    {
        return new WebMvcConfigurerAdapter()
        {
            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry)
            {
                if (!registry.hasMappingForPattern("/**"))
                {
                    // if this is executed spring won't add default resource
                    // locations - add them to the staticContentLocations if
                    // you want to keep them
                    // default locations:
                    // WebMvcAutoConfiguration.RESOURCE_LOCATIONS
                    registry.addResourceHandler("/**").addResourceLocations(
                            staticContentLocations);
                }
            }
        };
    }

如果 C:/myprj/static 有 index.html ,那么http://localhost:portno/index.html应该可以工作。希望有帮助。

于 2016-01-29T13:29:53.483 回答
3

有两件事需要考虑(Spring Boot v1.5.2.RELEASE)-

1)检查所有Controller类的@EnableWebMvc注解,如果有则删除

2) 检查使用注解的控制器类——@RestController 或@Controller。

不要在一个类中混合使用 Rest API 和 MVC 行为。对于 MVC,使用 @Controller,对于 REST API,使用 @RestController

Doing above 2 things resolved my issue. Now my spring boot is loading static resources with out any issues.
@Controller => load index.html => loads static files.

@Controller
public class WelcomeController {

    // inject via application.properties
    @Value("${welcome.message:Hello}")
    private String message = "Hello World";

    @RequestMapping("/welcome")
    public String welcome(Map<String, Object> model) {
        model.put("message", this.message);
        return "welcome";
    }

    @RequestMapping("/")
    public String home(Map<String, Object> model) {
        model.put("message", this.message);
        return "index";
    }

}

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />


    <link rel="stylesheet/less" th:href="@{/webapp/assets/theme.siberia.less}"/>

    <!-- The app's logic -->
    <script type="text/javascript" data-main="/webapp/app" th:src="@{/webapp/libs/require.js}"></script>
    <script type="text/javascript">
        require.config({
            paths: { text:"/webapp/libs/text" }
        });
    </script>

     <!-- Development only -->
     <script type="text/javascript" th:src="@{/webapp/libs/less.min.js}"></script>


</head>
<body>

</body>
</html>
于 2017-08-01T15:30:38.310 回答
3

我不得不向 pom.xml 添加 thymeleaf 依赖项。没有这个依赖,Spring boot 找不到静态资源。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
于 2020-10-01T07:16:48.580 回答
2

Spring Boot 将用于WebMvcAutoConfiguration配置静态内容,该类仅在您没有自定义WebMvcConfigurationSupportbean 时才会生效,在我的情况下,我确实有一个。

@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
        WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
        ValidationAutoConfiguration.class })
    public class WebMvcAutoConfiguration {

}

所以我只需要自己配置它,这是我的解决方案:

@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/static-file/**").addResourceLocations("classpath:/static/");
}
于 2018-08-29T02:42:09.500 回答
0

我在静态目录中有一个资产文件夹,并允许在 SpringConfig 中扩展WebSecurityConfigurerAdapter.

http.authorizeRequests().antMatchers("/", "/login", "/assets/**")
            .permitAll()
于 2018-10-18T11:18:57.473 回答
0

当我尝试从我现有的工作解决方案中创建一个沙箱示例作为模板(https://github.com/fluentcodes/sandbox/tree/java-spring-boot)时,我偶然发现了这个 404 主题:没有静态内容 index.html提供。

由于该示例相当简单并且现有解决方案有效,因此我没有深入研究提到的深挖弹簧解决方案。

我查看了创建的目标类,没有预期的 static/index.html 。

原因很简单:我不是在src/main/下创建资源,而是在src / 下创建资源。需要一些时间来寻找,因为提到了很多复杂的解决方案。对我来说,它有一个相当微不足道的原因。

另一方面,在启动 Spring Boot 时:为什么我没有得到任何提示,即找不到来自 location1、location2 .... locationx 的静态内容。认为它是一个话题。

于 2020-09-03T17:25:34.450 回答