Spring Boot不提供静态内容

Vin*_*lho 154 spring spring-mvc spring-boot

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

我已经放在一个命名的文件夹staticsrc/main/resources.在里面我有一个名为的文件夹images.当我打包应用程序并运行它时,它找不到我放在该文件夹上的图像.

我试图把静态文件中public,resourcesMETA-INF/resources但没有任何工程.

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

有什么想法为什么spring-boot没有找到这个?(我使用的是1.1.4 BTW)

Abh*_*kar 158

一年多以后没有提高死亡人数,但所有以前的答案都错过了一些关键点:

  1. @EnableWebMvc在你的课上将禁用org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.如果您想要完全控制,那就没关系,否则,这是一个问题.
  2. 除了已经提供的内容之外,无需编写任何代码来为静态资源添加其他位置.看着org.springframework.boot.autoconfigure.web.ResourceProperties从v1.3.0.RELEASE,我看到一个字段staticLocations,可以在配置application.properties.这是源代码的片段:

    /**
     * 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;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如前所述,请求URL将对于这些位置进行解析.因此,src/main/resources/static/index.html当请求URL 为时,将提供服务/index.html.从Spring 4.1开始,负责解析路径的类是org.springframework.web.servlet.resource.PathResourceResolver.

  4. 默认情况下启用后缀模式匹配,这意味着对于请求URL /index.html,Spring将查找对应的处理程序/index.html.如果打算提供静态内容,这是一个问题.要禁用它,请扩展WebMvcConfigurerAdapter(但不要使用@EnableWebMvc)和覆盖configurePathMatch,如下所示:

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        super.configurePathMatch(configurer);
    
        configurer.setUseSuffixPatternMatch(false);
    }
    
    Run Code Online (Sandbox Code Playgroud)

恕我直言,在代码中减少错误的唯一方法是尽可能不编写代码.使用已经提供的内容,即使需要进行一些研究,回报也是值得的.

  • 这个答案确实经过多次研究.一个伟大的阅读 (2认同)
  • 如果我举足轻重,我会回答这个问题并将其放入Spring Boot文档中 (2认同)
  • @Abhijit Sarkar我的意思是_Pivotal_公司,对您的不良感受深表歉意,但这不是故意的。如果我正确的话,Pivotal是Spring的所有者。我可以记录下来,但是他们中有人为此付钱,所以他们应该这样做:P (2认同)
  • _在代码中减少错误的唯一方法就是不要编写代码[...] _就像这样. (2认同)

Fra*_*ois 69

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

@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {

    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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我有同样的问题,相同版本的 Spring Boot 但这对我也不起作用 (3认同)

Eng*_*ery 47

我有类似的问题,事实证明,简单的解决方案是让我的配置类扩展WebMvcAutoConfiguration:

@Configuration
@EnableWebMvc
@ComponentScan
public class ServerConfiguration extends WebMvcAutoConfiguration{
}
Run Code Online (Sandbox Code Playgroud)

我不需要任何其他代码来允许我的静态内容被提供,但是,我确实将一个名为publicunder 的目录src/main/webapp和配置为maven 的目录指向src/main/webapp为资源目录.这意味着将public其复制到target/classes,并因此在运行时的类路径上为spring-boot/tomcat查找.


小智 24

查找映射到"/"或没有路径映射的控制器.

我遇到了这样一个问题,得到了405个错误,并且在几天内困扰我的脑袋.问题原来是一个带@RestController注释的控制器,我忘了用@RequestMapping注释注释.我猜这个映射路径默认为"/"并阻止静态内容资源映射.

  • @Shafiul否添加EnableAutoConfiguration和SpringBootApplication都是多余的!"@SpringBootApplication"包含"@EnableAutoConfiguration" (3认同)
  • 帮我解决了!我有一个用 @RestController("/blubb") 注释的控制器,这显然是错误的,但有时你看不到树木的木材。将其更改为 @RestController @RequestMapping("/blubb") 解决了它 (2认同)
  • 如果意图既为静态内容提供服务又为根请求提供动态处理程序,也可以显式添加@RequestMapping("/"). (2认同)

Fra*_*eth 18

配置可以如下:

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcAutoConfigurationAdapter {

// specific project configuration

}
Run Code Online (Sandbox Code Playgroud)

这里重要的是你WebMvcConfig 可以覆盖addResourceHandlers方法,因此你需要显式调用super.addResourceHandlers(registry)(如果你对默认资源位置感到满意,你不需要覆盖任何方法).

需要在这里评论的另一件事是,那些默认的资源位置(/static,/public,/resources/META-INF/resources)将只如果有尚未映射到一个资源处理程序注册/**.

从此刻开始,如果您有一个src/main/resources/static/images名为image.jpg的例子,您可以使用以下URL访问它:( http://localhost:8080/images/image.jpg服务器在端口8080上启动,应用程序部署到根上下文).


mat*_*sev 11

你检查过Spring Boot参考文档了吗?

默认情况下,Spring Boot将从类路径中的/static(/public/resources/META-INF/resources)文件夹或ServletContext的根目录中提供静态内容.

您还可以将项目与使用Spring MVC服务Web内容的指南进行比较,或查看spring-boot-sample-web-ui项目的源代码.

  • 是的,我做了,这些是我尝试过的地方,正如文档所指示的那样。但没有任何作用。我不明白为什么根本找不到资源。我试图查看样本,奇怪的是没有样本使用文档提出的结构。您刚刚粘贴的那个使用了一个模板文件夹,我假设它是用于 thymeleaf 配置或速度的。 (2认同)
  • 我同意@ViniciusCarvalho,我已经尝试了所有可能的组合来将 css/js 放在正确的位置,但似乎无法做到这一点。即使我访问 localhost:8089/css/styles.css 我也看不到任何东西。我只有一条规则来改变车身颜色。 (2认同)

小智 7

我遇到了这个问题,然后意识到我已经在我的application.properties中定义了:

spring.resources.static-locations=file:/var/www/static
Run Code Online (Sandbox Code Playgroud)

这超越了我曾经尝试过的其他一切.在我的情况下,我想保留两者,所以我保留了财产并添加:

spring.resources.static-locations=file:/var/www/static,classpath:static
Run Code Online (Sandbox Code Playgroud)

其中src/main/resources/static提供的文件为localhost:{port} /file.html.

以上都没有为我工作,因为没有人提到这个可以很容易从网上复制以用于不同目的的小财产;)

希望能帮助到你!想象一下,对于有这个问题的人来说,它很适合这篇长篇文章.


Bal*_*Bal 6

只是为一个老问题添加另一个答案......人们已经提到@EnableWebMvc将阻止WebMvcAutoConfiguration加载,这是负责创建静态资源处理程序的代码。还有其他条件也会阻止WebMvcAutoConfiguration加载。最清楚的方法是查看源:

https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ WebMvcAutoConfiguration.java#L139-L141

在我的例子中,我包含了一个库,该库有一个从其扩展的类,WebMvcConfigurationSupport这是一个阻止自动配置的条件:

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
Run Code Online (Sandbox Code Playgroud)

重要的是要永远从延长WebMvcConfigurationSupport。相反,从WebMvcConfigurerAdapter.

更新:在 5.x 中执行此操作的正确方法是实现 WebMvcConfigurer


小智 5

这个解决方案对我有用:

首先在webapp/WEB-INF下放一个resources文件夹,结构如下

-- src
  -- main
    -- webapp
      -- WEB-INF
        -- resources
          -- css
          -- image
          -- js
          -- ...
Run Code Online (Sandbox Code Playgroud)

二、在spring配置文件中

@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter{

    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".html");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resource/**").addResourceLocations("WEB-INF/resources/");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后就可以访问你的资源内容了,比如 http://localhost:8080/resource/image/yourimage.jpg


Rem*_*usS 5

我认为之前的答案很好地解决了这个问题.但是,我想补充一点,在你的应用程序中启用Spring Security的情况下,你可能必须明确告诉Spring允许对其他静态资源目录的请求,例如"/ static/fonts".

在我的情况下,默认情况下我有"/ static/css","/ static/js","/ static/images",但我的Spring Security实现阻止了/ static/fonts/**.

下面是我如何解决这个问题的一个例子.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.....
    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/", "/fonts/**").permitAll().
        //other security configuration rules
    }
.....
}
Run Code Online (Sandbox Code Playgroud)