在springBoot項目中,springmvc的相關配置都在WebMvcAutoConfiguration類中css
public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); return; } Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); //===========webjars訪問=================== 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)); } } //===========靜態資源存放文件路徑================ private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
全部/webjars/ ,都去classpath:/META-INF/resources/webjars/找資源html
webjars:以jar包的方式引入靜態資源。官網java
引入:react
<dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.4.1</version> </dependency>
目錄結構:jquery
訪問:web
http://localhost:8080/webjars/jquery/3.4.1/jquery.jsspring
/**訪問當前項目的任何資源,靜態資源訪問文件目錄:緩存
classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/ /
訪問:springboot
靜態資源文件夾下全部index.html頁面,被/**映射
訪問:
http://localhost8080/index.html 或者 http://localhost8080/
@Bean public WelcomePageHandlerMapping welcomePageHandlerMapping(...) { WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping( new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(), this.mvcProperties.getStaticPathPattern()); welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider)); return welcomePageHandlerMapping; } private Optional<Resource> getWelcomePage() { String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations()); return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst(); }
@Configuration @ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true) public static class FaviconConfiguration { private final ResourceProperties resourceProperties; public FaviconConfiguration(ResourceProperties resourceProperties) { this.resourceProperties = resourceProperties; } @Bean public SimpleUrlHandlerMapping faviconHandlerMapping() { SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1); //全部 **/favicon.ico mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", faviconRequestHandler())); return mapping; } @Bean public ResourceHttpRequestHandler faviconRequestHandler() { ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler(); requestHandler .setLocations(this.resourceProperties.getFaviconLocations()); return requestHandler; } }
spring.mvc.favicon.enabled=true默認啓用 存放位置:靜態資源文件夾下 favicon.ico
@ConfigurationProperties(prefix = "spring.resources") public class ResourceProperties { //能夠設置和資源有關的參數,如緩存時間等 } 若是想改變靜態資源文件夾的路徑,修改yml: spring.resources.static-locations=classpath:/hello,classpath:/mystatic
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
切換thymeleaf版本(舊版本的springboot切換)
<properties> <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version> </properties>
springboot對thymeleaf的自動配置文件
表示:只要咱們把HTML頁面放在classpath:/templates/下,就能夠自動渲染了
@ConfigurationProperties(prefix = "spring.thymeleaf") public class ThymeleafProperties { private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8; //表示:只要咱們把HTML頁面放在classpath:/templates/下,就能夠自動渲染了 public static final String DEFAULT_PREFIX = "classpath:/templates/"; public static final String DEFAULT_SUFFIX = ".html"; }
###ThymeLeaf配置 spring: thymeleaf: #模板的模式,支持 HTML, XML TEXT JAVASCRIPT mode: HTML5 #編碼 可不用配置 encoding: UTF-8 #內容類別,可不用配置 content-type: text/html #開發配置爲false,避免修改模板還要重啓服務器 cache: false #配置模板路徑,默認是templates,能夠不用配置 prefix: classpath:/templates ##實際項目中可能會有不太嚴格的HTML格式,此時設置mode=HTML5將會對非嚴格的報錯,能夠參考如下配置: spring.thymeleaf.mode=LEGACYHTML5 ##你可能會發如今默認配置下,thymeleaf對.html的內容要求很嚴格,好比<meta charset="UTF-8" />, ##若是少最後的標籤封閉符號/,就會報錯而轉到錯誤頁。 #所以,建議增長下面這段: spring.thymeleaf.mode = LEGACYHTML5 ##spring.thymeleaf.mode的默認值是HTML5,實際上是一個很嚴格的檢查,改成LEGACYHTML5能夠獲得一個可能更友好 ##親切的格式要求。 ##須要注意的是,LEGACYHTML5須要搭配一個額外的庫NekoHTML纔可用。 <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version> </dependency>
常見的一些能夠被修改的配置:
# THYMELEAF (ThymeleafAutoConfiguration) spring.thymeleaf.cache=true spring.thymeleaf.check-template=true spring.thymeleaf.check-template-location=true spring.thymeleaf.enabled=true spring.thymeleaf.enable-spring-el-compiler=false spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.excluded-view-names= spring.thymeleaf.mode=HTML spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.reactive.chunked-mode-view-names= spring.thymeleaf.reactive.full-mode-view-names= spring.thymeleaf.reactive.media-types= spring.thymeleaf.suffix=.html spring.thymeleaf.template-resolver-order= spring.thymeleaf.view-names=
<html xmlns:th="http://www.thymeleaf.org">
文本內容(覆蓋):<div th:text="${hello}">默認文本內容</div> 替換原生屬性值:<div id="aa" class="bb" th:id="#{cc}" th:class="${dd}"></div>
①、 賦值、字符串拼接
+:字符串拼接字體串
簡化字符中拼接操做:(使用」|」包圍字符串,不須要對字符串使用」’」)
<input type="text" name="userName" value="James Carrot" th:value="${user.name}" /> <span th:text="'The name of the user is ' + ${user.name}" ></span> <span th:text="'The name of the user is ' + ${user.name} + '_' + ${user.age}"> </span> <span th:text="|Welcome to our application, ${user.name}!|"></span> 等價於 <span th:text="'Welcome to our application, ' + ${user.name} + '!'">
②、數字輸出和計算
<span th:text="2013">1492</span> <span th:text="2013 + 2">1494</span> <span th:if="${user.isAdmin()} == false"> false </span> <span th:if="${user.other} == null"> null</span>
③、算術表達式
*二進制運算 +, -, , /, %
布爾表達式 true, false, !, not
以及 and, or
<span th:text="${user.age} % 2 == 0"> </span> 結果:true <span th:text="true"> </span> 結果:true <span th:text="!(${user.age} % 2 == 0)"> </span> 結果:false <span th:text="(${user.age} % 2 == 0) and true"> </span>結果:true
④、比較操做符
比較 >, <, >=, <= (gt, lt, ge, le)
判斷 ==, != (eq, ne)
<span th:if="${user.age} > 18"> 大人 </span> <span th:if="${user.age} != 18"> 大人_no_equality </span>
⑤、條件操做符
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
<span th:text="${user.age}%2 == 0 ? 'even'"> </span> <span th:text="${user.age}%2 == 0 ? 'even' : 'odd'"> </span> <span th:if="${member.age lt 18}"> 未成年人! </span> <span th:if="${member.name eq '啊三'}"> 歡迎小三來訪問! </span> ##不知足判斷條件 <span th:unless="${member.age gt 18}"> 你還不滿18歲,不可以看電影! </span> ##switch分支判斷 <span th:switch="${member.uid}"> <p th:case="100"> uid爲101的員工來了 </p> <p th:case="99"> uid爲102的員工來了 </p> <p th:case="*"> 沒有匹配成功的數據! </p> </span>
⑥、調用對象的成員變量的屬性
<input type="text" name="userName" th:value="${family.father.name}" />
⑦、調用map對象的屬性
經過map的key從hashMap獲取對象的屬性name值: 可使用」.」或者使用」[]」獲取對象值
<input type="text" name="userName" th:value="${hashMap.hashMapKey.name}" /> 等價於 <input type="text" name="userName" th:value="${hashMap['hashMapKey'].name}" />
⑧、調用list對象的屬性
<input type="text" name="userName" th:value="${family.childList[0].name}" />
⑨、調用屬性的方法
<input type="text" name="userName" th:value="${family.father.name.toUpperCase()}" />
⑩、獲取原生對象
<p th:text="${#httpServletRequest.getRemoteAddr()}"/> <p th:text="${#httpServletRequest.getAttribute('requestMessage')}"/> <p th:text="${#httpSession.getId()}"/> <p th:text="${#httpServletRequest.getServletContext().getRealPath('/')}"/>
⑪、生成URL地址@{}
th:href生成的值替換的href值 @{}
url中加入變量值(orderId=${id})作爲url的請求參數
<!-- th:href生成的值替換<a>的href值; (orderId=${id})作爲url的請求參數 --> <a th:href="@{http://localhost:8080/order/details(orderId=${id})}">view</a> 結果: <a href="http://localhost:8080/order/details?orderId=123">view</a> <!-- 生成:/order/details?orderId=123 --> <a th:href="@{/order/details(orderId=${id})}">view</a> 結果: <a href="/order/details?orderId=123">view</a> <!-- 替換url中變量值,生成/order/123/details --> <a th:href="@{/order/{orderId}/details(orderId=${id})}">view</a> 結果: <a href="/order/123/details">view</a>
⑫、表達式工具對象
<body> <p th:text="${#dates.format(mydate,'yyyy-MM-dd')}"/> <p th:text="${#dates.format(mydate,'yyyy-MM-dd HH:mm:ss.SSS')}"/> <hr/> <p th:text="${#strings.replace('www.baidu.cn','.','$')}"/> <p th:text="${#strings.toUpperCase('www.baidu.cn')}"/> <p th:text="${#strings.trim('www.baidu.cn')}"/> <hr/> <p th:text="${#sets.contains(names,'boot-0')}"/> <p th:text="${#sets.contains(names,'boot-9')}"/> <p th:text="${#sets.size(names)}"/> <hr/> <p th:text="${#sets.contains(ids,0)}"/> <p th:text="${ids[1]}"/> <p th:text="${names[1]}"/> </body>
⑬、迭代
<!-- 經常使用的迭代 th:each 用法 --> <tr th:each="user : ${userList}"> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> <td th:text="${user.isAdmin}"></td> </tr> ##獲取迭代的中間的狀態,定義在iterStat中 index :當前節點的索引,從0開始 size : 迭代節點總數 even/odd:當前是偶數/奇數行,boolean值 first/last:當前是天天/最後一個元素 <!-- 獲取迭代的中間的狀態,定義在iterStat中--> <tr th:each="user,iterStat : ${userList}"> <!-- index: 當前迭代的索引 --> <td th:text="${iterStat.index }"></td> <!-- first: 當前元素是第一個元素; last: 當前元素是最後個元素 --> <td th:text="${iterStat.first } ? '第一個元素':(${iterStat.last} ? '最後一個元素':'')" ></td> <!-- --> <td th:text="${iterStat.odd} ? 'odd' : 'even'" ></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> <td th:text="${user.isAdmin}"></td> </tr>
⑭、條件語法
**th:if th:unless **
<!-- th:if:若是值是true,則打印<span>整個節點 --> <span th:if="${user.isAdmin}" th:text="${user.name} + '是管理員'"> </span> <!-- th:unless: 和th:if是相反功能,若是值爲false,則打印<span>整個節點 --> <span th:unless="not ${user.isAdmin}" th:text="${user.name} + '是管理員'"> </span> <!-- th:switch / th:case --> <div th:switch="${user.name}"> <p th:case="'admin'">User is an administrator</p> <!-- *: case的默認的選項 --> <p th:case="*">User is some other thing</p> </div>
⑮、模板template
在web開發中,咱們常常會將公共頭,公共尾,菜單等部分提取成模板供其它頁面使用。在thymeleaf中,經過th:fragment、th:include、th:replace、參數化模板配置、css選擇器加載代碼塊等實現。
公共頁 /templates/template/footer.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <meta charset="UTF-8" /> <body> <!-- th:fragment 定義用於加載的塊 --> <span th:fragment="copy"> 2017 hry loaded by fragment=copy</span> <span id="copy-section"> 2017 hry loaded by id=copy-section</span> <!-- 定義模板時,能夠傳入參數 --> <span th:fragment="frag(month, date) "> <span th:text="'welcome hry come in ' + ${month} + '-' + ${date}"></span> </span> </body> </html>
經過th:include在本頁中加載以上的代碼塊copy :
templatename::selector:」::」前面是模板文件名,後面是選擇器
::selector:只寫選擇器,這裏指fragment名稱,則加載本頁面對應的fragment
templatename:只寫模板文件名,則加載整個頁面
<!-- 語法說明 "::"前面是模板文件名,後面是選擇器 --> <div th:include="template/footer::copy"></div> <!-- 只寫選擇器,這裏指fragment名稱,則加載本頁面對應的fragment --> <div th:include="::#thispage"></div> <!-- 只寫模板文件名,則加載整個頁面 --> <div th:include="template/footer"></div> <!--本頁面的加載塊--> <span id="thispage"> div in this page. </span>
經過th:fragment和css選擇器加載代碼塊
<!-- 這裏加載」th:fragment 定義用於加載的塊「 --> <div th:include="template/footer::copy"></div> <!-- 這裏加載」id=copy-section「的節點 --> <div th:include="template/footer::#copy-section"></div>
th:include 和 th:replace
## th:include:加載模板的內容: 讀取加載節點的內容(不含節點名稱),替換div內容 ## th:replace:替換當前標籤爲模板中的標籤,加載的節點會整個替換掉加載他的div <!-- 加載模板的內容: 讀取加載節點的內容(不含節點名稱),替換<div>的內容 --> <div th:include="template/footer::copy">1</div> 結果: <div> 2017 hry loaded by fragment=copy</div> <!-- 替換當前標籤爲模板中的標籤: 加載的節點會整個替換掉加載他的<div> --> <div th:replace="template/footer::copy">2</div> 結果: <span> 2017 hry loaded by fragment=copy</span>
調用模板時傳遞參數
<div th:include="template/footer::frag(${month},${date})">...</div>