SpringBoot 之靜態資源


boot 的默認的靜態資源有多個, 由 ResourceProperties 配置了默認值:

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

具體的配置工作是WebMvcAutoConfiguration的ResourceChainResourceHandlerRegistrationCustomizer完成的。

其先后順序, 正是靜態資源的查找順序。 也就是說, 如果出現了多個同名的靜態資源, 那么以 前面找到的為准。 假設下面的目錄結構:

resources
    META-INF
        resources
            subDir
                aaaa.html
            aa.html
            lk.jsp
    public
        aa.html
    resources
        aa.html
    static
        aa.html
        err.html
    templates
        aa.html
        aaxx.html
        errorrr.html
    application.properties

我們訪問 aa.html , 且假設沒有 /aa或 /aa.html 的映射, 那么 META-INF.resources 下面的 aa.html 會被首先訪問,其次是 resources目錄下面的,再次是 static, 最后是 public。

這里的靜態資源,可以是 html , js,css, pnp 等圖片, pdf, excel , doc,ppt等,也甚至可以是jsp, 但是, 我測試過, 如果把jsp 當作靜態資源,直接訪問的話, 那么 瀏覽器是識別不了的,那么就會出現一個下載框(或者直接下載)。 總之,只要我們的請求路徑是 上面RESOURCE_LOCATIONS 之一開頭的,但是它和我們的配置,比如@RequestMapping,沖突了。 那么boot 優先使用 顯式的@RequestMapping配置。

 

需要特別特別注意的是, 如果 靜態資源的裸文件名,也就是文件去后綴后的文件名,如果 和某個 @RequestMapping 沖突了, 那么我們就無法直接訪問這個 靜態資源了!!!因為@RequestMapping 是可以忽略后綴匹配的。  這個時候,我們實際是訪問了一個 @RequestMapping, 響應結果當然是由這個 方法來確定的。

 

boot, 當然也是額外提供了 對這個 靜態資源位置的配置的:

spring.mvc.static-path-pattern=    # 默認值為 /**

 

# 默認值為 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
spring.resources.static-locations= 這里設置要指向的路徑,多個使用英文逗號隔開,

使用 spring.mvc.static-path-pattern 可以重新定義pattern,如修改為 /myres/** ,則訪問static 等目錄下的fengjing.jpg文件應該為 http://localhost:8080/myres/fengjing.jpg ,修改之前為 http://localhost:8080/fengjing.jpg 。 spring.mvc.static-path-pattern 的格式必須是 xx/* xx/**  /xx/* /xx/** , 我這里已經說的很明白了吧, 只有4種, 其實就兩種, xx/*  /xx/* 等價,是一個意思, 貌似boot 會自動給第一個路徑補一個斜杠,如果沒有的話(推薦使用斜杠開頭的方式, 這樣會讓boot 少走一些“彎路”)。 而xx/* xx/** 的區別是, 一級目錄,和多層級目錄的區別了, 是 ant 目錄格式。 當然, 我們也可以去掉星號,配置成 /xx  /xx/yy, 這個是什么? 有些怪異了,我也迷糊了, 我也就不明白了。


注意 spring.mvc.static-path-pattern 只可以定義一個,目前不支持多個逗號分割的方式。

 

使用 spring.resources.static-locations 可以重新定義 pattern 所指向的路徑,支持 classpath: 和 file: (上面已經做過說明) ,如果我們不寫 classpath或file 前綴, 那么boot 是識別不了的!!! 而且呢, boot 也是不會報錯的! 這個真的有些坑啊! 另外, 記住,配置 spring.resources.static-locations 的值的先后順序就是查找的順序!!

 

另外,spring.resources.static-locations還可以配置成空,坑!! 比如我不小心配置下面這個樣, 結果boot 也生效了, 而且沒報錯!但這樣之后我就訪問不了任何靜態資源了。。坑!!:

spring.resources.static-locations=

 

 

對靜態文件的處理(主要是定位工作), 是org.springframework.web.servlet.resource.ResourceHttpRequestHandler 完成的。

ResourceHttpRequestHandler 完全是spring mvc 的范疇了。 它的作用就是找到那個url 對應的資源(通常是html/css/js之類的)然后檢查是否被改變,如果未改變則直接返回304.改變則返回新內容。

 

除此之外, 我們可以編程方式添加 靜態資源位置:

@Configuration
public class MyWebAppConfigurer 
        extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/myres/**").addResourceLocations("classpath:/myres/");
        super.addResourceHandlers(registry);
    }

}

 

 

參考:

http://blog.csdn.net/catoop/article/details/50501706 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM