1. 程式人生 > 實用技巧 >SpringBoot第四集:靜態資源與首頁定(2020最新最易懂)

SpringBoot第四集:靜態資源與首頁定(2020最新最易懂)

SpringBoot第四集:靜態資源與首頁定(2020最新最易懂)

問題

  SpringBoot構建的專案結構如下:沒有webapp目錄,沒有WEB-INF等目錄,那麼如果開發web專案,專案資源放在那裡呢?

WEB專案資源:靜態資源/動態資源。例如:css,圖片,jsp,模板引擎等。

一.SpringBoot工程靜態資源處理

  實際上,我們新建的SpringBoot工程預設提供的兩個目錄就是存放靜態資源的

  src/main/resources/static:靜態資源預設存放目錄(img,css,js,html等)

  src/main/resources/templates:模板引擎資源預設存放目錄(freemarker,Thymeleaf等)

  當然遠不止於此:檢視SpringBoot原始碼WebMvcAutoConfiguration類(上一集附錄中說到,所有自動裝配的原始碼類都是以XxxAutoConfiguration命名的,WEB開發自動裝配類就是WebMvcAutoConfiguration)Eclipse快捷鍵:Ctrol+Shift+T搜尋類WebMvcAutoConfiguration原始碼如下:

 1 /**
 2 * 新增資源的處理器方法(引數registry:資源處理器物件)
 3 */
 4 @Override
 5 public void addResourceHandlers(ResourceHandlerRegistry registry) {
6 // 判斷資源地址是否被自定義(在核心配置檔案中這樣配置就可以自定義靜態資源地址:spring.mvc.static-path-pattern=/xsge/) 7 if (!this.resourceProperties.isAddMappings()) { 8 // 如果自定義資源地址後,則禁用預設資源配置:就不用看下面的原始碼了 9 logger.debug("Default resource handling disabled"); 10 return;// 結束 11 } 12 // 利用resourceProperties(資源配置屬性物件)獲取快取控制(在這裡可以檢視resourceProperties原始碼可以看到自動裝配的預設資源地址)
13 CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); 14 // 如果存在對映地址/webjars/**(簡單來說,SpringBoot可以識別/webjars/**目錄下的所有資源) 15 if (!registry.hasMappingForPattern("/webjars/**")) { 16 customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**") 17 // 當訪問/webjars/**地址下的檔案時,實際將地址對映到/META-INF/resources/webjars/目錄下 18 /** 19 * 例如:http://localhost:8080/webjars/... 20 * 實際載入的地址:http://localhost:8080/META-INF/resources/webjars/.... 21 */ 22 .addResourceLocations("classpath:/META-INF/resources/webjars/") 23 .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); 24 /** 25 * webjars是個啥?是一種靜態資源的Mavne引入方式。 26 * 例如JQuery引入時,可以選擇離線檔案,線上引入,也可以使用Mavne依賴引入。 27 * 開啟webjars官網:https://www.webjars.org/,即可選擇想引入的web依賴 28 * 例如:需要引入JQuery,修改pom,加如依賴如下。 29 * <dependency> 30 * <groupId>org.webjars</groupId> 31 * <artifactId>jquery</artifactId> 32 * <version>3.5.1</version> 33 * </dependency> 34 * 頁面請求地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js就可以請求到 35 * 當然實際的訪問地址為:http://localhost:8080/META-INF/resources/webjars/jquery/3.5.1/jquery.js 36 */ 37 } 38 // 獲取靜態路徑路徑(在這裡可以查getStaticPathPattern原始碼獲取的靜態資源路徑是什麼/**:專案資源下的任意路徑) 39 String staticPathPattern = this.mvcProperties.getStaticPathPattern(); 40 // 判斷是否存在靜態資源路徑對映 41 if (!registry.hasMappingForPattern(staticPathPattern)) { 42 // 如果不存在,則新增靜態資源對映 43 customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern) 44 //新增資源對映地址(this.resourceProperties獲取resourceProperties配置的可用靜態資源地址) 45 .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())) 46 .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); 47 } 48 } 49 50 51 @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false) 52 public class ResourceProperties { 53 // 資源屬性配置,可自動裝配讀取的地址有:resources,static,public等 54 private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/", 55 "classpath:/resources/", "classpath:/static/", "classpath:/public/" }; 56 /** 57 * 這些預設資源地址 58 * classpath:/META-INF/resources/:這個地址當以Maven方式引入webjars依賴時,Maven依賴中存在(這個不屬於我們手動配置的,可以暫忽略不計) 59 * classpath:/resources/:在專案src/main/resources還可以在生成目錄resources,屬於靜態資源可識別目錄(需手動新建) 60 * classpath:/static/:在專案src/main/resources還可以在生成目錄static,屬於靜態資源預設目錄(專案新建後預設已建立的目錄) 61 * classpath:/public/:在專案src/main/resources還可以在生成目錄public,屬於靜態資源可識別目錄(需手動新建) 62 * 當每個目錄都存在時,載入的優先順序如下: 63 *   resources > static(預設目錄) > public 64 * 通常: 65 * resources:存放上傳下載的檔案 66 * static:存放專案靜態資源(img/js/css等) 67 * public:存放公共資源(比如離線方式匯入的JQuery) 68 */

總結:

  1.靜態資源可以放的目錄有:

    classpath:/resources/:實際地址為src/main/resources/resources,目錄須手動建立

    classpath:/static/:實際地址為src/main/resources/static,目錄由專案預設新建

    classpath:/public/:實際地址為src/main/resources/public,目錄須手動建立

    classpath:/**:實際地址為src/main/resources/下,新增任意目錄作為資源地址,通常用於自定義地址

自定義靜態資源地址,要求必須在yml配置檔案中宣告:spring.mvc.static-path-pattern=/xsge/

  2.訪問方式:預設訪問的根路徑都為http://localhost:8080/……

    例如:在resources/static/public任意目錄下存放xsge.jpg

    訪問地址都是:http://localhost:8080/xsge.jpg

防止有些人基礎不紮實,在這裡提示,預設的訪問路徑是http://localhost:8080/xsge.jpg,即applicaiton.yml配置檔案沒有自定義訪問路徑是前提。如果你在applicaiton.yml配置檔案中定製了訪問地址(server.servlet.context-path: /web),那麼就需要靈活變動了(http://localhost:8080/web/xsge.jpg)。

  3.如果三個靜態資源地址中存在相同的檔案時。

    訪問優先順序:resources > static(預設目錄) > public

2.首頁定製

  在沒有整合SpringBoot之前,我們新建的WEB專案,在WEB-INF目錄下都會有一個核心配置檔案web.xml。我們可以在web.xml中配置標籤<welcome-list>,通過該配置定製預設首頁。然後SpringBoot專案中沒有webapp目錄更沒有WEB-INF/web.xml檔案的,那麼該如何定製專案的預設首頁呢?

  SpringBoot框架在整合時,幫我們預設提供了首頁處理器方法。同上檢視原始碼:WebMvcAutoConfiguration如下:

 1 /**
 2  * 歡迎頁面對映處理器方法
 3  */
 4 @Bean    // 交給Spring容器管理,即:Spring容器載入,該程式也執行了
 5 public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
 6         FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
 7     WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
 8             new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
 9             this.mvcProperties.getStaticPathPattern());
10     welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
11     welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
12     return welcomePageHandlerMapping;
13 }
14 /**
15  * 獲取歡迎首頁的方法
16  */
17 private Optional<Resource> getWelcomePage() {
18     String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
19     return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
20 }
21 /**
22  * 獲取載入的首頁地址。
23  * 返回值為:資源地址/index.html(資源地址預設為resource/static/public)
24  */
25 private Resource getIndexHtml(String location) {
26     return this.resourceLoader.getResource(location + "index.html");
27 }

  總結:

  1.SpringBoot定製預設首頁,將首頁檔案命名為index.html,且放入到resource/static/public的任意目錄下即可。

  2.SpringBoot-2.1.0版本以前還可以自定義網站主題圖示ico。只要在appliction.yml中配置開啟預設圖示(spring.mvc.favicon.enabled :false),並將命名為favicon.ico的圖示放在resource/static/public的任意目錄下即可實現。

ICO圖示定製說明:出於安全考慮,SpringBoot後來捨棄了自定義網站主題圖示ico的功能。(除此之外個人理解頁面中直接使用連結方式更好一些)

首頁定製說明:一般情況下,我們很少直接使用html檔案作為模板,往往都是JSP,freemarker,Thymeleaf等,當然使用這些模板檔案時,通常將檔案放在templates目錄下(除JSP外,因為SpringBoot預設不支援JSP模板),需要注意的是該目錄下的資源,不能像靜態資源地址一樣直接訪問,必須提供控制器跳轉和模板引擎支援。(所以請看後續)