Spring Boot入門教程(十九): Thymeleaf
一:Thymeleaf
Spring官方也推薦使用Thymeleaf,Thymeleaf最大的特點是能夠直接在瀏覽器中開啟並正確顯示模板頁面,而不需要啟動整個Web應用。
JSP技術Spring Boot官方是不推薦的,原因有三:
- tomcat只支援war的打包方式,不支援可執行的jar。
- Jetty 巢狀的容器不支援jsp
- Undertow
- 建立自定義error.jsp頁面不會覆蓋錯誤處理的預設檢視,而應該使用自定義錯誤頁面
1. pom.xml
<dependency>
<groupId>org.springframework.boot</groupId >
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId >
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
spring-boot-starter-thymeleaf會自動包含spring-boot-starter-web,所以我們就不需要單獨引入web依賴了
2. application.properties
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf .encoding=UTF-8
spring.thymeleaf.mode=HTML5
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=true
spring.thymeleaf.enabled=true
預設的配置如下:
# THYMELEAF (ThymeleafAutoConfiguration)
#開啟模板快取(預設值:true)
spring.thymeleaf.cache=true
#Check that the template exists before rendering it.
spring.thymeleaf.check-template=true
#檢查模板位置是否正確(預設值:true)
spring.thymeleaf.check-template-location=true
#Content-Type的值(預設值:text/html)
spring.thymeleaf.content-type=text/html
#開啟MVC Thymeleaf檢視解析(預設值:true)
spring.thymeleaf.enabled=true
#模板編碼
spring.thymeleaf.encoding=UTF-8
#要被排除在解析之外的檢視名稱列表,用逗號分隔
spring.thymeleaf.excluded-view-names=
#要運用於模板之上的模板模式。另見StandardTemplate-ModeHandlers(預設值:HTML5)
spring.thymeleaf.mode=HTML5
#在構建URL時新增到檢視名稱前的字首(預設值:classpath:/templates/)
spring.thymeleaf.prefix=classpath:/templates/
#在構建URL時新增到檢視名稱後的字尾(預設值:.html)
spring.thymeleaf.suffix=.html
#Thymeleaf模板解析器在解析器鏈中的順序。預設情況下,它排第一位。順序從1開始,只有在定義了額外的TemplateResolver Bean時才需要設定這個屬性。
spring.thymeleaf.template-resolver-order=
#可解析的檢視名稱列表,用逗號分隔
spring.thymeleaf.view-names=
3. controller
@Controller
public class SampleController {
@GetMapping("/index")
public ModelAndView index(Model model){
ModelAndView modelAndView = new ModelAndView("index");
List<Fans> fans = new ArrayList<>();
fans.add(new Fans(1L, "zhangsan"));
fans.add(new Fans(2L, "lis"));
fans.add(new Fans(3L, "wangwu"));
modelAndView.addObject("user", new User(1L, "mengday", "[email protected]", fans, true, new Date()));
return modelAndView;
}
@Data
@AllArgsConstructor
public class User {
private Long id;
private String username;
private String email;
private List<Fans> fans;
private Boolean isAdmin;
private Date birthday;
}
@Data
@AllArgsConstructor
public class Fans {
private Long id;
private String name;
}
}
4. index.html
注意:在html標籤中使用xmlns:th=”http://www.thymeleaf.org”
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<link rel="stylesheet" type="text/css" href="css/style.css"/>
<body>
<div th:object="${user}">
<span th:text="*{id}"></span><br/>
<span th:text="'nickname:' + *{username}"></span><br/>
<span th:text="|email: ${user.email}|"></span><br/>
<span th:if="${user.isAdmin}">超級管理員</span><br/>
<span th:unless="${user.isAdmin == true}">普通使用者</span><br/>
<span> [[${#dates.format(user.birthday,'yyyy-MM-dd HH:mm:ss')}]] </span><br/>
<table border="1px" >
<tr> <td>index</td> <td>id</td> <td>name</td> <td>length</td></tr>
<tr th:each="item, stat : ${user.fans}" th:style="'background-color:' + ${stat.even == true ? 'bisque' : 'gray'}">
<td>[[${stat.index}]]</td>
<td>[[${item.id}]]</td>
<td>
<a th:href="@{/fans/{id}(id=${item.id})}">[[${item.name}]]</a>
</td>
<td>[[${#strings.length(user.username)}]]</td>
</tr>
</table>
</div>
<br/>
</body>
</html>
src/resources/static/css/style.css
一般靜態資源(js、css、image等)都放在static目錄下
body {
color: red;
}
二:靜態資源的存放位置
Spring Boot 提供了對靜態資源的支援,在建立Spring Boot專案時預設只建立了一個存放靜態資源的目錄src/main/resources/static,一共有四個,其它三個如果需要可以手動創建出目錄,而且這四個是有優先順序,當同一個資源出現在靜態目錄的多個地方時是按照優先順序獲取的,先獲取優先順序高的。
- classpath:/META-INF/resources
- classpath:/resources
- classpath:/static
- classpath:/public
1. application.properties配置
對應的原始碼:spring-configuration-metadata.json
{
"sourceType": "org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties",
"defaultValue": "\/**",
"name": "spring.mvc.static-path-pattern",
"description": "Path pattern used for static resources.",
"type": "java.lang.String"
},
{
"sourceType": "org.springframework.boot.autoconfigure.web.ResourceProperties",
"defaultValue": [
"classpath:\/META-INF\/resources\/",
"classpath:\/resources\/",
"classpath:\/static\/",
"classpath:\/public\/"
],
"name": "spring.resources.static-locations",
"description": "Locations of static resources. Defaults to classpath:[\/META-INF\/resources\/,\n \/resources\/, \/static\/, \/public\/].",
"type": "java.lang.String[]"
},
對應application.properties的預設配置
spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
在應用程式啟動的時候會有日誌列印,可以看到
- /** 對映到 /static (或/public、/resources、/META-INF/resources)
- /webjars/** 對映到 classpath:/META-INF/resources/webjars/
假如 在src/main/resources/static目錄下放一個index.html, 通過http://localhost:8080/index.html就能直接訪問,路徑中不用在包含static子路徑了。
如果訪問靜態資源想在路徑上有體現,也可以自定義,如將static-path-pattern配置成spring.mvc.static-path-pattern=/static/**
就需要用http://localhost:8080/static/index.html來訪問
同樣如果對於系統定義的靜態資源的存放位置不滿意也可以通過spring.resources.static-locations來定義,一般靜態資源都放在src/main/resource下面。
2. JavaConfig - WebMvcConfigurationSupport
addResourceHandlers用於配置spring.mvc.static-path-pattern。
傳統Spring MVC開發經常將jsp頁面放置在webapp/WEB-INF下,這樣要想訪問頁面就需要寫一個controller對應的方法,即使方法中沒什麼業務邏輯,只僅僅用於頁面跳轉也不得不寫,感覺有點low,在Spring Boot中通過配置addViewControllers,配置一個路徑和一個檢視名稱的對映即可,也不用再controller中寫頁面跳轉的RequestMapping方法了。囉嗦一句:看到addViewControllers這個方法感覺突然好熟悉,原來在iOS中有個addChildViewController方法,而且在iOS中有UIViewController這種類,類似於Java中的Controller的概念
@Configuration
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurationSupport {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/html/");
// addResourceLocations也可以指定一個系統中的一個目錄
// registry.addResourceHandler("/static/**").addResourceLocations("file:/Users/xxx/Documents/demo/static");
super.addResourceHandlers(registry);
}
// http://localhost:8080/home
@Override
protected void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
super.addViewControllers(registry);
}
}
webjars
webjars 就是將web開發中常用的靜態資源放到classpath:/META-INF/resources/webjars/ 中,然後打包成.jar釋出到maven倉庫中,使用時通過maven來引入,假如專案中用到bootstrap,常規的做法就是手動去官網下載,然後手動將bootstrap放到靜態目錄。一般常用的像jquery、bootstrap、angularjs、react、vue、swagger-ui等都有相應的maven依賴,目前有92個這種依賴。
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
在頁面上通過/webjars/jquery/3.3.1/jquery.js 來引入,Spring Boot 預設將 /webjars/** 對映到 classpath:/META-INF/resources/webjars/,可以通過http://localhost:8080/webjars/jquery/3.3.1/jquery.js來驗證一下看是否能獲取到。
<script src="${pageContext.request.contextPath}/webjars/jquery/3.3.1/jquery.js"></script>
webjars-locator
在上面訪問靜態資源時路徑中包含了版本號(http://localhost:8080/webjars/jquery/3.3.1/jquery.js),假如版本升級需要全域性替換所有引入的檔案,當然也不太費事一個全域性替換就搞定了,當然也可以防止於未然,webjars提供了一個webjars-locator的依賴,目的是讓前端頁面引入的靜態資源不包含路徑,當請求一個靜態資源時會自動幫你對映到對的版本對應的資源。
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.33</version>
</dependency>
@Controller
public class WebJarsController {
private final WebJarAssetLocator assetLocator = new WebJarAssetLocator();
@ResponseBody
@RequestMapping("/webjarslocator/{webjar}/**")
public ResponseEntity<Object> locateWebjarAsset(@PathVariable String webjar, HttpServletRequest request) {
try {
// /webjarslocator/jquery/
String mvcPrefix = "/webjarslocator/" + webjar + "/"; // This prefix must match the mapping path!
// /webjarslocator/jquery/jquery.js
String mvcPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
// META-INF/resources/webjars/jquery/3.3.1/jquery.js
String fullPath = assetLocator.getFullPath(webjar, mvcPath.substring(mvcPrefix.length()));
return new ResponseEntity<>(new ClassPathResource(fullPath), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
}
<script src="${pageContext.request.contextPath}/webjarslocator/jquery/jquery.js"></script>
假如前端訪問http://localhost:8080/webjarslocator/jquery/jquery.js(此地址中不包含版本號),地址對映到WebJarsController,返回META-INF/resources/webjars/jquery/3.3.1/jquery.js對應的資源。這樣就達到前端引入的靜態資源中不包含具體版本號,當需要升級的時候直接修改maven對應的依賴版本即可,前端也不用全域性替換版本號操作了。感覺這個功能不實用,版本升級很久才會一次,而且全域性替換也很簡單,也是秒秒鐘搞定的事情。
靜態資源瀏覽器快取
開發時,業務對應的js經常會變動,一般瀏覽器會快取靜態資源,一般防止瀏覽器快取靜態資源的做法是在地址後面使用版本號引數,或者在地址後面使用時間戳,Spring Boot 給出了自己的解決方案。
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
@ControllerAdvice
public class ResourceUrlProviderController {
@Autowired
private ResourceUrlProvider resourceUrlProvider;
@ModelAttribute("urls")
public ResourceUrlProvider urls() {
return this.resourceUrlProvider;
}
}
common.js放在 src/main/resources/static/js/目錄下
<script src="${pageContext.request.contextPath }${urls.getForLookupPath('/js/common.js') }"></script>
當我們訪問頁面後,HTML中實際生成的程式碼為common-<md5>.js, 每當common.js內容發生變化時MD5值就會重新生成,當js檔案沒有時md5值不變,當js檔案內容發生改變時,md5值發生變化,js檔案的內容也隨之改變。這樣就保證了js檔案始終是最新的。
<script src="/js/common-c6b7da8fffc9be141b48c073e39c7340.js"></script>
三: Interceptor攔截器
攔截器的使用分兩步:
- 宣告攔截器,實現HandlerInterceptor
- 配置攔截器,在WebMvcConfigurerAdapter#addInterceptors配置
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println(request.getRequestURI() + "-------------");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("------------postHandle------------");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("------------afterCompletion------------");
}
}
@Configuration
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
super.addResourceHandlers(registry);
}
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/");
super.addInterceptors(registry);
}
}
相關推薦
Spring Boot入門教程(十九): Thymeleaf
一:Thymeleaf Spring官方也推薦使用Thymeleaf,Thymeleaf最大的特點是能夠直接在瀏覽器中開啟並正確顯示模板頁面,而不需要啟動整個Web應用。 JSP技術Spring Boot官方是不推薦的,原因有三: tomcat只支援wa
Spring Boot入門教程(四十九): Dubbo
一:簡介 Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高效能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向介面的遠端方法呼叫,智慧容錯和負載均衡,以及服務自動註冊和發現。 二:安裝dubbo管理控制檯(dubbo-admin)
Spring Boot入門教程(四十六): @Async
一:簡介 ThreadPoolTaskExecutor 用於定義執行緒池,是對java.util.concurrent.ThreadPoolExecutor類的包裝。可以通過@EnableAsync來開啟非同步支援,通過@Async來宣告一個非同步方法 二:示例 @Confi
Spring Boot入門教程(四十五): 事務@Transactional
一:簡介 在Spring中事務可以通過兩種方式來管理,一種是程式設計式事務另一種是宣告式事務 宣告式事務:@Transactional 在方法的開頭開始事務,在方法的結束提交事務 程式設計式事務:TransactionTemplate或者PlatformTransa
Spring Boot入門教程(四十八):初始化操作 CommandLineRunner和ApplicationRunner
CommandLineRunner和ApplicationRunner在SpringApplication.run()之前,在所有的beans載入完成之後執行,用於執行一些初始化操作(如載入快取、讀取配置檔案、建立執行緒池等) CommandLineRunner和Applicatio
Spring Boot入門教程(五十): httpclient
在開發中經常會遇到呼叫第三方的介面,這裡介紹一下在spring boot中如何使用httpclient來發送get和post請求。 引入依賴 <dependency> <groupId>org.apache.httpco
Spring Boot入門教程(四十):微信支付整合-刷卡支付
一:準備工作 使用微信支付需要先開通服務號,然後還要開通微信支付,最後還要配置一些開發引數,過程比較多。 二:支付方式 刷卡支付(MICROPAY) :刷卡支付是使用者展示微信錢包內的“刷卡條碼/二維碼”給商戶系統掃描後直接完成支付的模式。主要應
Spring Boot入門教程(五十二): 在Docker上執行Spring Boot
一:基礎示例 1.1 安裝JDK和Maven 安裝openjdk: yum -y install java-1.8.0-openjdk* export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_
Spring Boot入門教程(五十一): JSON Web Token(JWT)
一:認證 在瞭解JWT之前先來回顧一下傳統session認證和基於token認證。 1.1 傳統session認證 http協議是一種無狀態協議,即瀏覽器傳送請求到伺服器,伺服器是不知道這個請求是哪個使用者發來的。為了讓伺服器知道請求是哪個使用者發來的,需要讓使用者提供
Spring Boot入門教程(四十四): Sharding-JDBC+JPA|MyBatis+Druid分庫分表實現
一:資料庫分片方案 客戶端代理: 分片邏輯在應用端,封裝在jar包中,通過修改或者封裝JDBC層來實現。 噹噹網的 Sharding-JDBC 、阿里的TDDL是兩種比較常用的實現。 中介軟體代理: 在應用和資料中間加了一個代理層。分片邏輯統一維護在中介軟體
Spring Boot入門教程(三十一): 自定義Starter
在springboot中,使用的最多的就是starter。starter可以理解為一個可拔插式的外掛,例如,你想使用jdbc外掛,那麼可以使用spring-boot-starter-jdbc;如果想使用mongodb,可以使用spring-boot-starte
Spring Boot2 系列教程(十九)Spring Boot 整合 JdbcTemplate
在 Java 領域,資料持久化有幾個常見的方案,有 Spring 自帶的 JdbcTemplate 、有 MyBatis,還有 JPA,在這些方案中,最簡單的就是 Spring 自帶的 JdbcTemplate 了,這個東西雖然沒有 MyBatis 那麼方便,但是比起最開始的 Jdbc 已經強了很多了,它沒有
Spring Boot參考教程(九)配置上傳下載
.net blog 不想 center src 默認 tps servlet odi 7.配置上傳下載 使用上傳下載的功能我們需要配置multipartResolver,先啟動工程,不做配置。 訪問端點/beans: Spring Boot默認實例化了一個Multip
Spring Boot系列教程十一: Mybatis使用分頁外掛PageHelper
一.前言 上篇部落格中介紹了spring boot整合mybatis的方法,基於上篇文章這裡主要介紹如何使用分頁外掛PageHelper。在MyBatis中提供了攔截器介面,我們可以使用PageHelp最為一個外掛裝入到SqlSessionFactory,實現攔截器功能。
Spring Boot入門二:使用ThymeLeaf+表單驗證
Thymeleaf提供了一個用於整合Spring MVC的可選模組,在應用開發中,你可以使用Thymeleaf來完全代替JSP,或其他模板引擎,如Velocity、FreeMarker等。Thymeleaf的主要目標在於提供一種可被瀏覽器正確顯示的、格式良
spring boot最新教程(十):在spring boot中使用攔截器
前一篇博文對過濾器的定義做了說明,過濾器屬於Servlet範疇的API,與Spring 沒什麼關係。Web開發中,我們除了使用 Filter 來過濾請web求外,還可以使用Spring提供的HandlerInterceptor(攔截器)。HandlerInte
Spring Boot 入門教程學習 (按照spring boot官方文件和自己理解整理)
建立Spring Boot maven專案 1. 在spring 官網中建立專案到本地 首先選擇maven project java 之後 填寫 group id Artifactid 完成之後, 點選 generate Project 生成本地專
Spring Boot入門教程(四十三): API介面設計之token、timestamp、sign
一:token 簡介 Token:訪問令牌access token, 用於介面中, 用於標識介面呼叫者的身份、憑證,減少使用者名稱和密碼的傳輸次數。一般情況下客戶端(介面呼叫方)需要先向伺服器端申請一個介面呼叫的賬號,伺服器會給出一個appId和一個key,
Spring Boot入門教程(四):配置檔案
配置方式 每個starter都有自己預設的配置,如果需要改變預設值,可以在其他地方配置來覆蓋掉預設的值,覆蓋預設的配置有多種方式,每種方式的優先順序也不同,如果在多個地方配置則優先使用優先順序高的值,其中命令列引數優先順序最高, 其中大部分引數一般都配置在屬性
Spring boot 入門教程-token驗證
我們在做專案時比如商城專案,有的頁面的開啟是需要登陸的而有的頁面則不需要,所以這裡就需要一種驗證是否登入,或者登入是否過期,這裡說一種token令牌+攔截器的方式。 生成token 使用JWT。 1.引入 <dependency>