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
