靜態資源
在 SpringBoot項目中,默認是沒有webapp文件夾的
如果你在創建項目時有添加 web的依賴,那它本身就是一個 web項目。
那問題也就接踵而至,沒有web文件夾 我們的靜態資源應該放哪里呢。
我們將項目結構展開,掃一眼 猜測的話應該是放到這兩個文件夾中。
我們先看看放到 static
文件夾中靜態資源能否訪問
隨便編寫一個 js文件,並通過瀏覽器對其進行測試訪問
沒有問題能夠訪問到,也就是說我們的靜態資源可以放在這個文件夾底下。
我們來了解一下為什么放到這個文件夾底下,雖然很容易猜到是放到這里,但我們要知其所以然。
我們點開 SpringBoot用於存放自動配置類的地方,找到我們的 MVC自動配置類
在其自動配置類中有這么一段代碼,這段代碼能為我們解惑。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 如果對靜態資源路徑進行了自定義操作,則只有自定義的靜態資源路徑生效。
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
// 還引入了webjars 通過jar包的形式也能夠訪問靜態資源
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
// 默認路徑相關
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
自定義路徑
自定義路徑很好理解,就是通過配置文件的形式 對靜態資源加載路徑進行自定義操作。
/**
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/].
*/
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
這是存在於自動配置類中的屬性(也就是我們可以配置的配置項)。
我們可以通過的spring.resources.static-locations=
來對靜態資源加載路徑進行配置,一旦配置后 默認的靜態資源加載路徑就會失效。SpringBoot會以我們配置的路徑為准。(默認的路徑下面會說)
一般和spring.mvc.static-Path-Pattern=
配合使用,下面的代碼為yaml格式,實際上二者並無太多差別。
spring:
resources:
static-locations: classpath:molu/
mvc:
static-path-pattern: /m/*
我們通過自定義配置,指定靜態資源加載的位置為 resources
目錄下的molu文件夾。
並對 url進行了一些處理,我們每次訪問都需要在前面加上一個 /m才行。
如下圖:
關於靜態資源的加載位置,我們一般使用默認的就好 自定義顯得有些華而不實 如果你沒有特定需求的話。
WebJars
我們在開發Java web項目的時候會使用像Maven,Gradle等構建工具以實現對jar包版本依賴管理,以及項目的自動化管理,但是對於JavaScript,Css等前端資源包,我們只能采用拷貝到webapp下的方式,這樣做就無法對這些資源進行依賴管理。那么WebJars就提供給我們這些前端資源的jar包形勢,我們就可以進行依賴管理。
這個沒什么好說的,用的也少 感興趣可以看看這篇博客
默認路徑
關於默認路徑有哪些,我們可以通過在配置文件中點進 static-locations
一探究竟
可以看到,默認的靜態資源加載位置有四個。也有人說是五個, 但 /** 那個我實在是測不出來,可能是我環境有問題.......
/META-INF/resources/
/resources/
/static/
/public/
/**
(假裝有五個)
上面這些靜態資源加載位置可以同時存在,且存在優先級 優先級也就是寫的順序。
靜態資源的默認訪問優先級:/META-INF/resources/
>/resources/
>/static/
>/public/
首頁和圖標
解決了靜態資源位置,我們來看看首頁應該如何處理。
SpringBoot創建的項目默認是沒有首頁的,如果訪問 localhost:8080
,會返回一個 error頁面。
我們通過閱讀源碼(mvc 自動配置類),很容易的就能夠知道該問題應該如何解決
@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;
}
private Optional<Resource> getWelcomePage() {
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}
private Resource getIndexHtml(String location) {
return this.resourceLoader.getResource(location + "index.html");
}
private boolean isReadable(Resource resource) {
try {
return resource.exists() && (resource.getURL() != null);
}
catch (Exception ex) {
return false;
}
}
大致的意思就是,會在我們的靜態資源目錄中,找一個文件名為 index.html 的文件來作為首頁。
我們測試一下:
確實能夠實現,那還有沒有其他方式呢?
答案是有的。我們還可以將首頁放在 templates
文件夾中,使用 thymeleaf
模板引擎來實現該功能 。
Thymeleaf
Thymeleaf是一個Java / XML / XHTML / HTML5模板引擎 ,可以在Web(基於Servlet)和非Web環境中工作。 它更適合在基於MVC的Web應用程序的視圖層提供XHTML / HTML5,但它甚至可以在脫機環境中處理任何XML文件。 它提供完整的Spring Framework。
在Web應用程序中,Thymeleaf旨在成為JavaServerPage(JSP)的完全替代品,並實現自然模板的概念:模板文件可以直接在瀏覽器中打開,並且仍然可以正確顯示為網頁。
馬上步入2021的現在,jsp已經慢慢淡出人們的視線。而其替代品thymeleaf
,SpringBoot也是比較推薦的。
關於模板引擎的一些概念性的東西我就不寫了,網上一搜一籮筐。我們直接講如何使用(實現首頁的跳轉)。
在使用之前我們首先導入依賴
- 可以導入對應的starter
- 也可以直接導入相關的兩個依賴
導入依賴后,我們了解一下 thymeleaf
能夠配置的配置項。
在對SpringBoot自動裝配原理了解過后,我們都知道大概率會存在這樣一個自動配置類:
該類中的所有屬性我們都可以在配置文件中,對其進行自定義配置。
進入該類后,第一眼就能看到以下這些屬性
// 編碼
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
// 前綴
public static final String DEFAULT_PREFIX = "classpath:/templates/";
// 后綴
public static final String DEFAULT_SUFFIX = ".html";
- 編碼應該不需要過多的解釋,默認為utf-8,你想改也能改 看個人需求。
- 而前后綴的話,則類似於我們之前配置的視圖解析器,要求你將 thymeleaf的頁面寫在"classpath:/templates/"路徑下,且以 .html 結尾。
- 當然,如果你有特定需求 也是可以對其進行修改的。
我們嘗試實現一下
在 templates 文件夾中編寫一個測試用的html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>thymeleaf Test</h1>
</body>
</html>
編寫視圖跳轉所需要的Controller類
@Controller
public class HelloController {
@RequestMapping("/test")
public String test(){
return "test!";
}
}
啟動項目,在瀏覽器中輸入 localhost:8080/test:
沒有任何問題,最簡單的使用還是很容易就能做到。
那我們要使用 thymeleaf
來做到首頁的跳轉,大致也就有了思路。
- 將
index.html
寫在templates
文件夾下 - 編寫
Controller
類
@Controller
public class HelloController {
@RequestMapping("/")
public String test(){
return "index";
}
}
訪問測試:
沒有任何問題.
關於 thymeleaf實際上能講的東西非常之多,這里只簡單涉及 之后有時間會另開一篇博客來講講 thymeleaf
圖標
我們還可以在靜態資源加載位置放一張圖片來作為我們的網頁圖標
- 我們將需要設置為圖標的圖片文件重命名為
favicon.ico
- 將重命名好的圖片文件移動至我們靜態資源加載的位置
圖片沒有損壞能夠正常打開就沒有問題
我們重啟項目,再次訪問
這個時候我們的網頁就存在圖標了。
好像2.20版本之前,還需要在配置文件中配置才能生效。
如果不確定你的版本是否能直接生效,你可以在配置文件中 輸入spring.mvc.favicon.enabled,如果沒有該配置項應該是能夠直接生效的。反之則需要配置為false
放松一下眼睛
夾帶私貨(不是