【问题标题】:Spring Boot app not serving static contentSpring Boot 应用程序不提供静态内容
【发布时间】:2015-05-24 05:18:49
【问题描述】:

我正在使用 Spring Boot,并试图在部署时使我的静态资源(CSS、JS、字体)可用。源代码供您查看或从https://github.com/joecracko/StaticResourceError 克隆。

现在我的 CSS、JS 和字体文件对我部署的网站不可见。

这是我的项目目录结构:

这是已编译 JAR 的根目录:我向您保证,这些文件存在于它们各自的文件夹中。

这是我看到的网络错误:

这里是我的 chrome 工具提供的源代码。请注意 bar.css 在这里显示为空。你可以看看我的源代码,看它不是空的。

这是我的主页.html

<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>

<!-- Main Styles -->
<link rel="stylesheet" href="/css/bar.css" />
<script src="/js/foo.js"></script>

</head>
<body>
    <div>Welcome to Foo!</div>
</body>
</html>

这是我的 Web 应用初始化程序 (FooWebAppInitializer.java)

public class FooWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {

        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ServletConfig.class);

        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));

        //Spring Security
        container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
            .addMappingForUrlPatterns(null, false, "/*");

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcherServlet", new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/*");
        dispatcher.addMapping("*.css");
        dispatcher.addMapping("*.eot");
        dispatcher.addMapping("*.svg");
        dispatcher.addMapping("*.ttf");
        dispatcher.addMapping("*.woff");
        dispatcher.addMapping("*.map");
        dispatcher.addMapping("*.js");
        dispatcher.addMapping("*.ico");
    }
}

这是我的 Servlet 配置 (ServletConfig.java)

@Configuration
@EnableWebMvc
@ComponentScan({"com.foo"})
public class ServletConfig extends WebMvcAutoConfiguration{

    @Bean
    MultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }

    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource source = new ResourceBundleMessageSource();
        source.setBasename("messages");
        return source;
    }
}

还有,我的 Spring Security Config (WebSecurityConfig.java)

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().permitAll();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**"); // #3
    }
}

【问题讨论】:

    标签: java spring spring-mvc configuration spring-boot


    【解决方案1】:

    静态资源放在目录下:

    /src/main/resources/static
    

    您也可以使用publicresources 代替static 作为文件夹名称。

    说明:您的构建工具(Maven 或 Gradle)将复制应用程序 classpath/src/main/resources/ 的所有内容,并且如 Spring Boot's docs 中所写,所有类路径中名为/static(或/public/resources)的目录中的内容将作为静态内容提供。


    这个目录也可以,但不鼓励:

    /src/main/webapp/
    

    不要使用 src/main/webapp 目录,如果您的应用程序将 包装成罐子。虽然这个目录是一个通用标准,但它 只适用于战争包装,它会被默默地忽略 如果您生成 jar,则大多数构建工具。

    【讨论】:

    • Spring Boot 文档说这不是 JAR 构建的最佳想法。 docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/…
    • 你成功了!将我的静态文件放入 src/main/resources/static/ 就像一个魅力!这就是我最终从我的 html 中引用它们的方式。 注意前面没有'static'。如果您能告诉我为什么这样有效,则可以加分。
    • 这两个答案都不好。您可能会遇到实时刷新问题。最好遵循 Spring Boot 文档并在 /static 下包含资源(在您的根项目文件夹之外 - 而不是在您的 src/main/resources 文件夹中)。然后,您将能够在 chrome 中进行更改,将它们保存在您的 chrome 工作区中,并且无需重新启动即可实时查看更新。此外,如果您要部署为 jar,maven 不会在 /static 文件夹中获取资源,因此要解决此问题,您需要阅读 /questions/27566967/no-mapping-found-for-http-request- with-uri-web-inf-pages-mainpage-jsp-in-disp/27567879#27567879
    • @JohnDeverall 感谢您指出可能存在的问题。我可以很好地理解实时刷新和here there are some solutions 的问题。您指出的另一个问题似乎与将内容放入 /src/main/webapp 并将应用程序打包为 jar 有关,但不鼓励在答案中使用此文件夹。那么,留在/src/main/resources/static,除了实时刷新,我们还有其他问题吗?
    • @Andrea 我提到的另一个问题与 Maven 的约定优于配置方法有关。 /static 不遵循 Maven 约定,因此 /static 中的任何内容都不会自动包含在构建工件中。您需要配置 maven,就像在另一个问题中一样,但使用 static 而不是 src/main/webapp。如果您选择 /src/main/resources/static 而不仅仅是静态,我不知道除了实时刷新之外您还会遇到任何其他问题
    【解决方案2】:

    有两件事需要考虑(Spring Boot v1.5.2.RELEASE)- 1)检查所有Controller类的@EnableWebMvc注解,如果有则删除 2) 检查使用注解的控制器类——@RestController 或@Controller。不要在一个类中混合使用 Rest API 和 MVC 行为。对于 MVC,使用 @Controller,对于 REST API,使用 @RestController

    以上 2 件事解决了我的问题。现在我的 Spring Boot 正在加载静态资源,没有任何问题。 @Controller => load index.html => 加载静态文件。

    @Controller
    public class WelcomeController {
    
        // inject via application.properties
        @Value("${welcome.message:Hello}")
        private String message = "Hello World";
    
    
        @RequestMapping("/")
        public String home(Map<String, Object> model) {
            model.put("message", this.message);
            return "index";
        }
    
    }
    

    index.html

    <!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>
    

    【讨论】:

      猜你喜欢
      • 2019-02-13
      • 2019-03-30
      • 2019-09-20
      • 2016-07-14
      • 2018-12-28
      • 1970-01-01
      • 2015-06-21
      • 2023-03-08
      相关资源
      最近更新 更多