SpringBoot 靜態(tài)資源導入及首頁設置問題
本節(jié)了解一下 SpringBoot 中 Web 開發(fā)的靜態(tài)資源導入和首頁設置,對應 SpringBoot-03-Web 項目。
1. 靜態(tài)資源導入
在 Web 開發(fā)過程中,我們需要接觸許多的靜態(tài)資源,如 CSS、JS、圖片等;在之前的開發(fā)過程中,這些資源都放在 Web 的目錄下,用到的時候按照對應路徑訪問即可。不過在 SpringBoot 項目中,沒有了 Web 的目錄,那這些靜態(tài)資源該放到哪里去,又要如何訪問呢?
由于是 Web 應用中的配置,所以查看對應的自動配置類 WebMvcAutoConfiguration,可以看到處理資源的方法 addResourceHandlers
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
registration.addResourceLocations(resource);
}
});
}
其中,this.resourceProperties.isAddMappings() 的作用為判斷是否在配置文件中指定了資源的訪問路徑,若指定了則此方法不用生效,直接返回;若未指定則繼續(xù)執(zhí)行方法,去默認的位置查找資源。
1.1 WebJars
WebJars 是前端資源的 Jar 包形式,讓我們可以通過 Jar 包的形式使用前端的框架、組件。
WebJars 網(wǎng)站:https://www.webjars.org/。
為什么要使用 WebJars?
我們在開發(fā) Java web 項目的時候會使用像 Maven,Gradle 等構(gòu)建工具以實現(xiàn)對 jar 包版本依賴管理,以及項目的自動化管理,但是對于 JS,Css 等前端資源包,我們只能采用拷貝到 webapp 目錄下的手工方式,這樣做就無法對這些資源進行依賴管理,而且容易導致文件混亂、版本不一致等問題。WebJars 就提供給我們這些前端資源的 jar 包形式,我們就可以進行依賴管理。
如要使用到 JQuery 時,按照之前的做法,我們要去網(wǎng)上下載 JQuery 的 JS 文件,把它放到 web 目錄下的 statics/js 下(之前用 AJAX 的時候就是這么干的);但現(xiàn)在,我們可以采用 WebJars 的方式。
首先在 WebJars 網(wǎng)站中找到 JQuery 的 Maven 坐標,把它放到項目的 pom 文件中
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.6.0</version>
</dependency>
引入后,在項目的 External Libaries 中就可以看到 org.webjars:jquery:3.6.0 了!

那么我們要怎么訪問到它呢?在上面的源碼中其實就已經(jīng)給出了路徑
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
這行代碼將 /webjars/ 下的所有訪問都映射為了 classpath:/META-INF/resources/webjars/,即我們只需要通過 /webjars/ 就可以找到類路徑下的 /jquery/3.6.0/jquery.js 文件了!
運行項目,在瀏覽器中輸入 http://localhost:8080/webjars/jquery/3.6.0/jquery.js,確實顯示出了 jquery.js 文件!
以 WebJars 方式引入的文件,都符合上圖中的結(jié)構(gòu),即能通過 classpath:/META-INF/resources/webjars/ 路徑訪問到,這樣代碼中的設置和外部文件就聯(lián)系起來了!
1.2 staticPathPattern
回到源碼中,這個方法的三句話還有最后一句(雖然很長但確實是一句)
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
registration.addResourceLocations(resource);
}
});
這就有點復雜了(之前版本的源碼倒還好理解一點),不過可以看到獲取靜態(tài)路徑 getStaticPathPattern() 方法,點進去
public String getStaticPathPattern() {
return this.staticPathPattern;
}
這個方法直接返回了 staticPathPattern,繼續(xù)點
/** * Path pattern used for static resources. */ private String staticPathPattern = "/**";
到這就明白了,其實就是默認的靜態(tài)資源路徑!這個路徑也可以通過 spring.mvc 去設置,在未設置的情況在,它就是項目下的所有路徑 /**!
然后在 Web 屬性類 WebProperties 中有一個資源類 Resource,它也設置了4個路徑(跳躍的有點大,先看著吧),其中
public static class Resources {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
...
}
classpath:/META-INF/resources/即上面的 WebJars 路徑classpath:/resources/即resources/resources/路徑classpath:/static/為resources/static/路徑classpath:/public/為resources/public路徑
即所有通過 /**(未配置情況下)的訪問請求,都會在這四個路徑中尋找靜態(tài)資源!
默認的 resource 中只有 static 一個目錄,這里把上面的目錄都創(chuàng)建一下,且放入一個測試用的 js 文件

此時運行項目,訪問 http://localhost:8080/public.js、http://localhost:8080/resources.js、http://localhost:8080/static.js,都可以顯示出對應的 js 文件內(nèi)容!
注意:如果三個目錄下的文件有重名的情況,則優(yōu)先級為 CLASSPATH_RESOURCE_LOCATIONS 數(shù)組的順序,可以理解為如果在前面的路徑中找到了就不找后面的了!
2. 首頁設置
和上面一樣,先找到對應的源碼
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
return welcomePageHandlerMapping;
}
很長也很復雜,不過只需要關(guān)注里面的 getWelcomePage() 方法,點進去看看
private Resource getWelcomePage() {
for (String location : this.resourceProperties.getStaticLocations()) {
Resource indexHtml = getIndexHtml(location);
if (indexHtml != null) {
return indexHtml;
}
}
ServletContext servletContext = getServletContext();
if (servletContext != null) {
return getIndexHtml(new ServletContextResource(servletContext, SERVLET_LOCATION));
}
return null;
}
private Resource getIndexHtml(String location) {
return getIndexHtml(this.resourceLoader.getResource(location));
}
private Resource getIndexHtml(Resource location) {
try {
Resource resource = location.createRelative("index.html");
if (resource.exists() && (resource.getURL() != null)) {
return resource;
}
}
catch (Exception ex) {
}
return null;
}
這三個方法是逐層調(diào)用的關(guān)系(雖然我也不知道為什么要這么干),不過可以知道,其中的 location 就是上面的三個目錄 resources、static、public,默認的首頁是 index.html。也就是說,如果這三個目錄下存在 index.html 文件,那么它就是默認的首頁!演示就省略了,反正也不是什么難點!
3. 總結(jié)
本節(jié)主要是從源碼的角度,研究了一下靜態(tài)資源導入和首頁設置的問題。其實學習結(jié)論很簡單,但從源碼出發(fā)思考問題的思想,是不容易學習的。
到此這篇關(guān)于SpringBoot 靜態(tài)資源導入及首頁設置的文章就介紹到這了,更多相關(guān)SpringBoot 靜態(tài)資源導入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot使用WebSocket實現(xiàn)前后端交互的操作方法
springboot使用websocket有兩種方式,一種是實現(xiàn)簡單的websocket,另外一種是實現(xiàn)STOMP協(xié)議,本篇講述如何使用springboot實現(xiàn)簡單的websocket,需要的朋友可以參考下2022-04-04
Java中String類(字符串操作)的10個常見問題和解決方法
這篇文章主要介紹了Java中String類(字符串)操作的10個常見問題,需要的朋友可以參考下2014-04-04
解決swagger2中@ApiResponse的response不起作用
這篇文章主要介紹了解決swagger2中@ApiResponse的response不起作用問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
聊聊ResourceBundle和properties讀取配置文件的區(qū)別
這篇文章主要介紹了ResourceBundle和properties讀取配置文件的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
fastjson轉(zhuǎn)換對象實體@JsonProperty不生效問題及解決
這篇文章主要介紹了fastjson轉(zhuǎn)換對象實體@JsonProperty不生效問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08

