您好,登錄后才能下訂單哦!
如何解決SpringBoot靜態(tài)資源導(dǎo)入及首頁設(shè)置的問題,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。
在 Web 開發(fā)過程中,我們需要接觸許多的靜態(tài)資源,如 CSS、JS、圖片等;在之前的開發(fā)過程中,這些資源都放在 Web 的目錄下,用到的時(shí)候按照對(duì)應(yīng)路徑訪問即可。不過在 SpringBoot 項(xiàng)目中,沒有了 Web 的目錄,那這些靜態(tài)資源該放到哪里去,又要如何訪問呢?
由于是 Web 應(yīng)用中的配置,所以查看對(duì)應(yīng)的自動(dòng)配置類 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í)行方法,去默認(rèn)的位置查找資源。
WebJars 是前端資源的 Jar 包形式,讓我們可以通過 Jar 包的形式使用前端的框架、組件。
WebJars 網(wǎng)站:https://www.webjars.org/。
為什么要使用 WebJars?
我們?cè)陂_發(fā) Java web 項(xiàng)目的時(shí)候會(huì)使用像 Maven,Gradle 等構(gòu)建工具以實(shí)現(xiàn)對(duì) jar 包版本依賴管理,以及項(xiàng)目的自動(dòng)化管理,但是對(duì)于 JS,Css 等前端資源包,我們只能采用拷貝到 webapp 目錄下的手工方式,這樣做就無法對(duì)這些資源進(jìn)行依賴管理,而且容易導(dǎo)致文件混亂、版本不一致等問題。WebJars 就提供給我們這些前端資源的 jar 包形式,我們就可以進(jìn)行依賴管理。
如要使用到 JQuery 時(shí),按照之前的做法,我們要去網(wǎng)上下載 JQuery 的 JS 文件,把它放到 web 目錄下的 statics/js 下(之前用 AJAX 的時(shí)候就是這么干的);但現(xiàn)在,我們可以采用 WebJars 的方式。
首先在 WebJars 網(wǎng)站中找到 JQuery 的 Maven 坐標(biāo),把它放到項(xiàng)目的 pom 文件中
<dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.6.0</version> </dependency>
引入后,在項(xiàng)目的 External Libaries 中就可以看到 org.webjars:jquery:3.6.0 了!
那么我們要怎么訪問到它呢?在上面的源碼中其實(shí)就已經(jīng)給出了路徑
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
這行代碼將 /webjars/
下的所有訪問都映射為了 classpath:/META-INF/resources/webjars/
,即我們只需要通過 /webjars/
就可以找到類路徑下的 /jquery/3.6.0/jquery.js
文件了!
運(yùn)行項(xiàng)目,在瀏覽器中輸入 http://localhost:8080/webjars/jquery/3.6.0/jquery.js
,確實(shí)顯示出了 jquery.js 文件!
以 WebJars 方式引入的文件,都符合上圖中的結(jié)構(gòu),即能通過 classpath:/META-INF/resources/webjars/
路徑訪問到,這樣代碼中的設(shè)置和外部文件就聯(lián)系起來了!
回到源碼中,這個(gè)方法的三句話還有最后一句(雖然很長(zhǎng)但確實(shí)是一句)
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); } });
這就有點(diǎn)復(fù)雜了(之前版本的源碼倒還好理解一點(diǎn)),不過可以看到獲取靜態(tài)路徑 getStaticPathPattern()
方法,點(diǎn)進(jìn)去
public String getStaticPathPattern() { return this.staticPathPattern; }
這個(gè)方法直接返回了 staticPathPattern
,繼續(xù)點(diǎn)
/** * Path pattern used for static resources. */ private String staticPathPattern = "/**";
到這就明白了,其實(shí)就是默認(rèn)的靜態(tài)資源路徑!這個(gè)路徑也可以通過 spring.mvc 去設(shè)置,在未設(shè)置的情況在,它就是項(xiàng)目下的所有路徑 /**
!
然后在 Web 屬性類 WebProperties 中有一個(gè)資源類 Resource
,它也設(shè)置了4個(gè)路徑(跳躍的有點(diǎn)大,先看著吧),其中
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
路徑
即所有通過 /**
(未配置情況下)的訪問請(qǐng)求,都會(huì)在這四個(gè)路徑中尋找靜態(tài)資源!
默認(rèn)的 resource 中只有 static 一個(gè)目錄,這里把上面的目錄都創(chuàng)建一下,且放入一個(gè)測(cè)試用的 js 文件
此時(shí)運(yùn)行項(xiàng)目,訪問 http://localhost:8080/public.js
、http://localhost:8080/resources.js
、http://localhost:8080/static.js
,都可以顯示出對(duì)應(yīng)的 js 文件內(nèi)容!
注意:如果三個(gè)目錄下的文件有重名的情況,則優(yōu)先級(jí)為 CLASSPATH_RESOURCE_LOCATIONS
數(shù)組的順序,可以理解為如果在前面的路徑中找到了就不找后面的了!
和上面一樣,先找到對(duì)應(yīng)的源碼
@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; }
很長(zhǎng)也很復(fù)雜,不過只需要關(guān)注里面的 getWelcomePage()
方法,點(diǎn)進(jìn)去看看
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; }
這三個(gè)方法是逐層調(diào)用的關(guān)系(雖然我也不知道為什么要這么干),不過可以知道,其中的 location
就是上面的三個(gè)目錄 resources
、static
、public
,默認(rèn)的首頁是 index.html
。也就是說,如果這三個(gè)目錄下存在 index.html
文件,那么它就是默認(rèn)的首頁!演示就省略了,反正也不是什么難點(diǎn)!
關(guān)于如何解決SpringBoot靜態(tài)資源導(dǎo)入及首頁設(shè)置的問題問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。