Springboot 系列(五)Spring Boot web 開發之靜態資源和模版引擎

前言

Spring Boot 天生的適合 web 應用開發,它能夠快速的嵌入 Tomcat, Jetty 或 Netty 用於包含一個 HTTP 服務器。且開發十分簡單,只須要引入 web 開發所需的包,而後編寫業務代碼便可。css

自動配置原理?

在進行 web 開發以前讓我再來回顧一下自動配置,能夠參考系列文章第三篇。Spring Boot 爲 Spring MVC 提供了自動配置,添加了以下的功能:html

  • 視圖解析的支持。
  • 靜態資源映射,WebJars 的支持。
  • 轉換器 Converter 的支持。
  • 自定義 Favicon 的支持。
  • 等等

在引入每一個包時候咱們須要思考是如何實現自動配置的,以及咱們能本身來配置哪些東西,這樣開發起來纔會駕輕就熟。java

關於 Spring Boot Web 開發的更詳細介紹能夠參考官方文檔。git

1. JSON 格式轉換

Spring Boot 默認使用 Jackson 進行 JSON 化處理,若是想要切換成 FastJson 能夠首先從官方文檔裏查詢信息。從這裏知道對於 ResponseBody 的渲染主要是經過 HttpMessageConverters, 而首先引入FastJson Pom依賴並排除 Spring Boot 自帶的 Jackson。github

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
     <exclusions>
           <exclusion>
               <artifactId>spring-boot-starter-json</artifactId>
               <groupId>org.springframework.boot</groupId>
           </exclusion>
     </exclusions>
</dependency> 
<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.47</version>
</dependency>
複製代碼

編寫轉換器處理 json 的日期格式同時處理中文亂碼問題。web

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    /** * 自定義JSON轉換器 * * @param converters */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        //日期格式化
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        //處理中文亂碼問題
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);

        converter.setSupportedMediaTypes(fastMediaTypes);
        converter.setFastJsonConfig(fastJsonConfig);

        converters.add(converter);
    }
    
}
複製代碼

2. 靜態資源映射

By default, Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext.面試

2.1 默認映射

官方文檔告訴咱們 Spring Boot 對於靜態資源的映射目錄是 /static , /public , /resources 以及 /META-INF/resource。除此以外其實還映射了 /webjars/**classpath:/META-INF/resources/webjarsspring

很明顯此處是自動配置實現的,經過查看源碼分析這段配置。 json

Mvc靜態資源映射
靜態資源映射

而對於網站圖標,Spring Boot 也已經配置了默認位置,能夠在看到。bootstrap

// path: org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
	SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
	mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
	mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", // 圖表
			faviconRequestHandler()));
	return mapping;
}

@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
	ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
	requestHandler.setLocations(resolveFaviconLocations());
	return requestHandler;
}

private List<Resource> resolveFaviconLocations() {
	String[] staticLocations = getResourceLocations(
			this.resourceProperties.getStaticLocations());
	List<Resource> locations = new ArrayList<>(staticLocations.length + 1);
	Arrays.stream(staticLocations).map(this.resourceLoader::getResource)
			.forEach(locations::add);
	locations.add(new ClassPathResource("/"));
	return Collections.unmodifiableList(locations);
}
複製代碼

根據 Spring Boot 默認的靜態資源映射規則,能夠直接把須要的靜態資源放在響應的文件夾下而後直接引用便可。

靜態資源映射

而放在 Public 文件夾下的 HTML 頁面也能夠直接訪問。

2.2 webjars

webjars 的思想是把靜態資源打包到 Jar 包中,而後使用 JVM 構建工具進行管理,如 maven , Gradle 等。

使用 webjars 第一步須要進入依賴,如要使用 bootstrap。

<!-- Web Jars 靜態資源文件 -->
 <dependency>
     <groupId>org.webjars</groupId>
     <artifactId>bootstrap</artifactId>
     <version>4.1.3</version>
</dependency>
複製代碼

引入以後查看 bootstrap 資源。

因爲 Springboot 映射了 /webjars/**classpath:/META-INF/resources/webjars. 所以能夠直接在文件中引用 webjars 的靜態資源。

<!-- Bootstrap core CSS -->
<link href="/webjars/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
<script src="/webjars/bootstrap/4.1.3/js/bootstrap.min.js"></script>
複製代碼

3. 模版引擎

Spring MVC 支持各類模版技術,如 Thymeleaf , FreeMarker , JSP 等。而Thyemeleaf 原型即頁面的特性或許更符合 Spring Boot 快速開發的思想而被官方推薦。

Thymeleaf 是適用於 Web 開發的服務端 Java 模版引擎,Thymeleaf 爲開發工做流程帶來優雅天然的模版,因爲其非侵入的特性,可讓頁面無論是在靜態原型下仍是用做模版引擎時都有良好的頁面展示。

<table>
  <thead>
    <tr>
      <th th:text="#{msgs.headers.name}">Name</th>
      <th th:text="#{msgs.headers.price}">Price</th>
    </tr>
  </thead>
  <tbody>
    <tr th:each="prod: ${allProducts}">
      <td th:text="${prod.name}">Oranges</td>
      <td th:text="${#numbers.formatDecimal(prod.price, 1, 2)}">0.99</td>
    </tr>
  </tbody>
</table>
複製代碼

3.1 引入 Thymeleaf

<!-- thymeleaf 模版-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
複製代碼

3.2 使用 Thymeleaf

根據 Spring Boot 自動配置原理,先看一下 Thymeleaf 的配置類,從中能夠看出 Thymeleaf 的相關配置。咱們能夠知道 默認存放目錄是 templates 文件夾,文件後綴爲 .html 且開啓了緩存。

@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

	private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;

	public static final String DEFAULT_PREFIX = "classpath:/templates/";

	public static final String DEFAULT_SUFFIX = ".html";
	/** * Whether to enable template caching. */
	private boolean cache = true;
複製代碼

爲了在開發中編寫模版文件時不用重啓,能夠在配置中關閉緩存。

# 關閉模版緩存
spring.thymeleaf.cache=false
# 若是須要進行其餘的配置,能夠參考配置類:ThymeleafProperties
# org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties
複製代碼

編寫 Controller 響應信息。

/** * 獲取ID爲1的用戶信息 * * @return */
    @GetMapping(value = "/user/1")
    public String getUserById(Model model) {
        User user1 = new User("Darcy", "password", 24, new Date(), Arrays.asList("Java", "GoLang"));
        User user2 = new User("Chris", "password", 22, new Date(), Arrays.asList("Java", "Web"));
        ArrayList<User> userList = new ArrayList<>();
        userList.add(user1);
        userList.add(user2);
        model.addAttribute("userList", userList);
        model.addAttribute("user", user1);
        return "user";
    }
複製代碼

由於 Thymelaf 默認模版位置在 templates 文件夾下,所以在這個文件夾下編寫頁面信息。

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Thymeleaf 的基本使用</title>
    <!-- 引入JS文件 -->
    <!--<script th:src="@{/static/js/alert.js}"></script>-->
</head>
<body>

<div>
    <p><b>Hello Thymeleaf Index</b></p>
    用戶名稱:<input th:id="${user.username}" th:name="${user.username}" th:value="${user.username}">
    <br/>
    用戶技能:<input th:value="${user.skills}">
    <br/>
    用戶年齡:<input th:value="${user.age}">
    <br/>
    用戶生日:<input th:value="${#dates.format(user.birthday,'yyyy-MM-dd hh:mm:ss ')}">
</div>


<div th:object="${user}">
    <p><b>Hello Thymeleaf Index</b></p>

    用戶名稱:<input th:id="*{username}" th:name="*{username}" th:value="*{username}">
    <br/>
    用戶技能:<input th:value="*{skills}">
    <br/>
    用戶年齡:<input th:value="*{age}">
    <br/>
    用戶生日:<input th:value="*{#dates.format(birthday,'yyyy-MM-dd hh:mm:ss')}">
</div>

<div>
    <p><b>Text 與 utext</b></p>
    <!-- th:text 顯示HTML源碼,做爲字符串 -->
    <span th:text="${user.username}">abc</span>
    <br>
    <span th:utext="${user.username}">abc</span>
</div>

<div>
    <p><b>URL 的引用</b></p>
    <a th:href="@{https://www.baidu.com}">網站網址</a>
</div>

<div>
    <p><b>表單的使用</b></p>
    <form th:action="@{/th/postform}" th:object="${user}" method="post">
        用戶名稱:<input type="text" th:field="*{username}">
        <br/>
        用戶技能:<input type="text" th:field="*{skills}">
        <br/>
        用戶年齡:<input type="text" th:field="*{age}">
        <input type="submit">
    </form>
</div>

<div>
    <p><b>判斷的使用</b></p>
    <div th:if="${user.age} == 18">18歲了</div>
    <div th:if="${user.age} gt 18">大於18歲</div>
    <div th:if="${user.age} lt 18">小於18歲</div>
    <div th:if="${user.age} ge 18">大於等於</div>
    <div th:if="${user.age} le 18">小於等於</div>
</div>

<div>
    <p><b>選擇框</b></p>
    <select>
        <option>請選擇一本書</option>
        <option th:selected="${user.username eq 'admin'}">管理員</option>
        <option th:selected="${user.username eq 'Darcy'}">Darcy</option>
        <option th:selected="${user.username eq 'Chris'}">Chris</option>
    </select>
</div>

<div>
    <p><b>遍歷功能</b></p>
    <table>
        <tr>
            <th>用戶名稱</th>
            <th>年齡</th>
            <th>技能</th>
        </tr>
        <tr th:each="u:${userList}">
            <td th:text="${u.username}"></td>
            <td th:text="${u.age}"></td>
            <td th:text="${u.skills}"></td>
        </tr>
    </table>
</div>

<div>
    <p><b>Switch功能</b></p>
    <div th:switch="${user.username}">
        <p th:case="'admin'">歡迎管理員</p>
    </div>
</div>
</body>
</html>
複製代碼

訪問頁面能夠看到數據正常顯示。

文章代碼已經上傳到 GitHub Spring Boot Web開發 - 靜態資源。 文章代碼已經上傳到 GitHub Spring Boot Web開發 - 模版引擎

<完>

我的網站:www.codingme.net
若是你喜歡這篇文章,能夠關注公衆號,謝謝支持喲 ❤ 。
關注公衆號回覆【資源】能夠沒有套路的獲取全網最火的的 Java 核心知識整理&面試資料。

公衆號
相關文章
相關標籤/搜索