【问题标题】:Spring Boot 2.4 application doesn't resolve static content with custom WebMvcConfigurer#addResourceHandlersSpring Boot 2.4 应用程序不使用自定义 WebMvcConfigurer#addResourceHandlers 解析静态内容
【发布时间】:2021-03-10 12:47:01
【问题描述】:

我有一个带有 Spring MVC 的“典型”(接近初始化项目的启动项目)Spring Boot 2.4 应用程序,我想向静态文件添加缓存。为此,我提供了我自己的@Configuration-class,它实现了WebMvcConfigurer。但无论我尝试什么,一旦我使用自己的配置,我总是会收到静态资源的 404 错误。

我的静态内容目录结构

src/main/resources/
|- static/
  |- res/
    |- css/
    |- js/
  |- images/
  |- favicon.ico

问题/疑问 我认为我的误解在于 ResourceHandlerRegistry#addResourceHandlerResourceHandlerRegistry#addResourceLocations 如何协同工作。

我尝试以类似于默认资源解析的方式进行操作(请参阅org.springframework.boot.autoconfigure.web.WebProperties.Resources.CLASSPATH_RESOURCE_LOCATIONS)并最终得到以下(无效)代码:

@Configuration
public class CacheStaticResourcesConfiguration implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(final ResourceHandlerRegistry registry) {
        registry
                .addResourceHandler("/favicon.ico", "/res/**", "/images/**")
                .addResourceLocations("classpath:/static")
                .setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)
                        .noTransform()
                        .mustRevalidate());
    }
}

【问题讨论】:

    标签: spring-boot spring-mvc


    【解决方案1】:

    资源/类路径的解析确实令人困惑,我也花了一点时间才理解它。以下包含大量 cmets 的示例有望阐明一切。

    TL;DR:

     registry
         // Request URLs
         .addResourceHandler("/**" /*, ... */)
         // Path inside application (refers to src/main/resources directory)
         // TRAILING SLASH IS IMPORTANT
         .addResourceLocations("classpath:/static/")
    

    Spring 将路径的可变部分从放入addResourceHandler() 的模式附加到.addResourceLocations() 中提供的资源位置。示例:

    // TRAILING SLASH IS IMPORTANT!
    .addResourceLocations("classpath:/static/")
     =>
        addResourceHandler("/**")
        => GET /res/css/main.css
           => resolved as: "classpath:/static/res/css/main.css"
        
        BUT
        
        addResourceHandler("/res/**")
        => GET /res/css/main.css
              (spring only appends the ** to the value from
               addResourceLocations())
           => resolved as: "classpath:/static/css/main.css"
    

    工作示例配置

    import org.springframework.boot.autoconfigure.web.WebProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.CacheControl;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    import java.util.concurrent.TimeUnit;
    
    @Configuration
    public class CacheStaticResourcesConfiguration implements WebMvcConfigurer {
    
        /**
         * We provide a custom configuration which resolves URL-Requests to static files in the
         * classpath (src/main/resources directory).
         *
         * This overloads a default configuration retrieved at least partly from
         * {@link WebProperties.Resources#getStaticLocations()}.
         *
         * @param registry ResourceHandlerRegistry
         */
        @Override
        public void addResourceHandlers(final ResourceHandlerRegistry registry) {
            /*
             * BE AWARE HERE:
             *
             * .addResourceHandler(): URL Paths
             * .addResourceLocations(): Paths in Classpath to look for file
             *   root "/" refers to src/main/resources
             *   For configuration example, see:
             *     org.springframework.boot.autoconfigure.web.WebProperties.Resources().getStaticLocations()
             *
             * .addResourceLocations("classpath:/static/")
             *   =>
             *      addResourceHandler("/**")
             *      => GET /res/css/main.css
             *         => resolved as: "classpath:/static/res/css/main.css"
             *      BUT
             *      addResourceHandler("/res/**")
             *      => GET /res/css/main.css
             *            (spring only appends the ** to the value from
             *             addResourceLocations())
             *         => resolved as: "classpath:/static/css/main.css"
             */
    
            registry
                    .addResourceHandler("/favicon.ico")
                    // trailing slash is important!
                    .addResourceLocations("classpath:/static/")
                    .setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS)
                            .noTransform()
                            .mustRevalidate());
    
            registry
                    .addResourceHandler("/res/**")
                    // trailing slash is important!
                    .addResourceLocations("classpath:/static/res/")
                    .setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)
                            .noTransform()
                            .mustRevalidate());
    
            registry
                    .addResourceHandler("/images/**")
                    // trailing slash is important!
                    .addResourceLocations("classpath:/static/images/")
                    .setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)
                            .noTransform()
                            .mustRevalidate());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-24
      • 1970-01-01
      • 2017-03-01
      • 1970-01-01
      • 2022-01-02
      • 2014-05-14
      • 2018-02-10
      相关资源
      最近更新 更多