SpringBoot起飛系列-Web開發(五)


一、前言

從今天你開始我們就開始進行我們的web開發,之前的一篇用SpringBoot起飛系列-使用idea搭建環境(二)已經說明了我們如何進行開發,當然這是搭建起步,接下來我們就開始進行詳細的開發,包括springboot中各種starters的使用,真正的使用到的功能都是我們實際項目中能用到的。

這里要提到的時,springboot的開發是分模塊化的,每個模塊可以對應一個starter,例如:web開發模塊就對應spring-boot-starter-web,除此之外還有訪問數據庫的模塊、Redis模塊等等,我們需要什么樣的功能就去引入什么模塊,這樣我們的項目管理起來也是十分方便,項目的條理也更加的清晰。

首先我們要搭建一個web項目,所以我們要先選中web模塊,這是必須的,之后的模塊需要什么我們再逐一引入。

二、SpringBoot的Web開發約定

2.1 配置約定

俗話說,springboot這個框架本身就是用約定大於配置的方式設計的,很多配置都成了我們的約定(默認的配置),我們雖然可以更改,但是還是有必要知道的。下面我們簡單介紹一下springboot的自動配置原理,這就是springboot中的約定的實現方法。

首先,springboot會把配置文件中以某個前綴開頭的配置映射的bean中去,這樣我們的配置就在程序啟動的時候成了一個一個bean,使用起來也比較方便,默認情況下springboot會用一個Configuration和一個Properites類來配置,如下:

xxxxAutoConfiguration:幫我們給容器中自動配置組件;
xxxxProperties:配置類來封裝配置文件的內容;

每一個的AutoConfiguration對應一個Properties,springboot中所有的配置都是這么實現的。xxxAutoConfiguration類都是容器中的一個組件,都加入到容器中;用他們來做自動配置;xxxProperties是接受配置的bean。

我們以HttpEncodingAutoConfiguration(Http編碼自動配置)為例解釋自動配置原理:

@Configuration   //表示這是一個配置類,以前編寫的配置文件一樣,也可以給容器中添加組件
@EnableConfigurationProperties(HttpEncodingProperties.class)  //啟動指定類的ConfigurationProperties功能;將配置文件中對應的值和HttpEncodingProperties綁定起來;並把HttpEncodingProperties加入到ioc容器中

@ConditionalOnWebApplication //Spring底層@Conditional注解(Spring注解版),根據不同的條件,如果滿足指定的條件,整個配置類里面的配置就會生效;    判斷當前應用是否是web應用,如果是,當前配置類生效

@ConditionalOnClass(CharacterEncodingFilter.class)  //判斷當前項目有沒有這個類CharacterEncodingFilter;SpringMVC中進行亂碼解決的過濾器;

@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)  //判斷配置文件中是否存在某個配置  spring.http.encoding.enabled;如果不存在,判斷也是成立的
//即使我們配置文件中不配置pring.http.encoding.enabled=true,也是默認生效的;
public class HttpEncodingAutoConfiguration {
  
      //他已經和SpringBoot的配置文件映射了
      private final HttpEncodingProperties properties;
  
   //只有一個有參構造器的情況下,參數的值就會從容器中拿
      public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
        this.properties = properties;
    }
  
    @Bean   //給容器中添加一個組件,這個組件的某些值需要從properties中獲取
    @ConditionalOnMissingBean(CharacterEncodingFilter.class) //判斷容器沒有這個組件?
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
        return filter;
    }

所以說springboot有很多這樣的類,我們默認只關注配置的prefix就行了, 這是我們以后要覆蓋修改springboot的默認配置所需要的配置key。

2.2 靜態資源映射約定

首先我們可以先看一下靜態資源的配置類,和我們上邊說的是一樣的,前綴使用的是spring.resources:

@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware {
  //可以設置和靜態資源有關的參數,緩存時間等
}

具體代碼就不再貼了,直接說結果吧,如果我們用maven管理下載我們的靜態資源包時,比如jquery.js什么的,那么我們的默認訪問路徑是 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找資源。

webjars:http://www.webjars.org/,是以jar包的方式引入靜態資源。例如我們引入jquery.js庫,那么可以再pom.xml中這么寫:

<!--引入jquery-webjar-->在訪問的時候只需要寫webjars下面資源的名稱即可
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

訪問地址:localhost:8080/webjars/jquery/3.3.1/jquery.js

如果我們以普通的方式訪問我們的靜態資源,如html,css,js什么的,所有的訪問路徑都會從下邊的路徑里邊去找,classpath:指的就是我們的resources文件夾。優先級:/META-INF/resources>resources>static>public。

"classpath:/META-INF/resources/", 
"classpath:/resources/",
"classpath:/static/", 
"classpath:/public/" 
"/":當前項目的根路徑

http://localhost:8080/asserts/css/index.css對應static/asserts/css/index.css。

三、模板引擎

3.1 介紹

模板引擎可能這個詞聽起來很高大上,其實我們之前就接觸過,最早的就是jsp,還有現在比較高級的Velocity、Freemarker、Thymeleaf,其實模板引擎這一類的功能大都具有以下特點,我們可以用一張圖來解釋:

都是數據+表達式,生成html,原理都很簡單了,只是我們看哪個寫起來比較順手,功能更加強大了。springboot推薦使用Thymeleaf來作為模板引擎。

3.2 引入Thymeleaf

首先引入依賴:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

然后在resources文件夾下添加templates文件夾,下邊添加一個index.html,因為默認配置thymeleaf用的前綴是classpath:/templates,后綴是.html。

然后我們添加一個HomeController,設置為mvc的控制器,用@Controller注解,如果你用了RestController就直接返回字符串了而不是去找視圖了。

@Controller
@RequestMapping("/home")
public class HomeController {

    @RequestMapping("/index")
    public String index(ModelMap map) {
        map.put("hello","你好");
        return "index";
    }
}

然后修改index.html模板,寫上thymeleaf語法:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>成功!</h1>
    <!--th:text 將div里面的文本內容設置為 -->
    <div th:text="${hello}">這是顯示歡迎信息</div>
</body>
</html>

其中xmlns:th="http://www.thymeleaf.org",是導入名稱空間,可以讓我們編碼的時候有thymeleaf語法提示,不得不說這語法和vue是一樣的啊。

我們直接訪問http://localhost:8080/home/index就可以看到效果了。

3.3 設置默認啟動頁

當我們訪問一個站點域名的時候,可以默認設置跳轉到哪一個頁面,這也是許多網站最基本的操作。

下邊我們添加一個配置類WebConfig,來設置啟動頁:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    //所有的WebMvcConfigurerAdapter組件都會一起起作用
    @Bean //將組件注冊在容器
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
        WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("forward:/home/index");
                registry.addViewController("/index.html").setViewName("forward:/home/index");
            }
        };
        return adapter;
    }
}

上邊代碼的意思是放我們訪問/或者/index.html的時候,默認轉發到/home/index路徑,我們直接設置home/index的頁面就行了。

3.4 Thymeleaf語法

3.4.1 標准表達式

使用${},和ognl表達式一樣,也是為了照顧我們jsp的開發習慣。

java代碼:

@Controller
@RequestMapping("/home")
public class HomeController {

    @RequestMapping("/index")
    public String index(Map<String,Object> map) {
        map.put("hello","你好啊");
        Person person = new Person();
        person.setName("zhangsan");
        person.setAge(25);
        map.put("person",person);
        return "home/index";
    }
}

html代碼:

<body>
    <h1>成功!</h1>
    <!--th:text 將div里面的文本內容設置為 -->
    <div th:text="${hello}">這是顯示歡迎信息</div>
    <br>

    <p>姓名:<span th:text="${person.name}"></span></p>
    <p>年齡:<span th:text="${person.age}"></span></p>
</body>

3.4.2 選擇變量表達式

選擇變量表達式,也叫星號變量表達式,使用th:object屬性來綁定對象。

html代碼:

<p>==========選擇變量表達式===========</p>
<div th:object="${person}">
    <div th:text="*{name}"></div>
    <div th:text="*{age}"></div>
</div>

選擇變量表達式使用th:object來表示要選擇的對象,然后使用*來代表這個對象,后邊的{}里邊寫對象中的屬性。

也可以直接使用*{person.name}來獲取數據,不同的是${}是在上細紋的map中獲取數據,而*是在選擇的對象上獲取數據。

<p>==========選擇變量表達式===========</p>
<div >
    <div th:text="*{person.name}"></div>
    <div th:text="*{person.age}"></div>
</div>

3.4.3 url表達式

生成一個url地址或者一個路徑。可用於<script src="..">、<link href="..">、<a href="..">等。

<p>==========Url表達式===========</p>
<div >
    <!--相對路徑-->
    <a th:href="@{'person?name='+${person.name}}" >地址1</a>
    <!--相對於項目的根路徑-->
    <a th:href="@{'/person?name='+${person.name}}" >地址2</a>
</div>
<script th:src="@{'/asserts/js/index.js'}"></script>

幾乎所有的html屬性都能用th:xxx的形式替換,經過thymeleaf解析后會直接替換為原始html屬性和值。

3.4.4 內置對象

thymeleaf提供了一些內置對象,可以讓我們直接使用,訪問一些請求信息。

#request:

${#request.getContextPath()} 

${#request.getAttribute("name")}

#session:

{#session.getAttribute("loginUser")}

{#session.id}

3.4.5 工具對象

工具對象可以幫助我們格式化一樣數據,簡單的處理一數據。

  • #dates:java.util.Date對象的實用方法,<span th:text="${#dates.format(curDate,'yyyy-MM-dd HH:mm:ss')}"></span>
  • #calendars:和dates類似,但是是java.util.Calendar對象。
  • #numbers:格式化數據對象的實用方法。
  • #strings:字符串對象的實用方法。contains,startsWith,prepending/appending等。
  • #objects:對objects操作的實用方法。
  • #bools:對布爾值求值的實用方法。
  • #arrays:數組的實用方法。
  • #lists:list的實用方法.
  • #sets:set的實用方法.
  • #maps:map的實用方法
  • #aggregates:對數組或集合創建聚合的實用方法。

3.4.6 thymeleaf模板片段與布局頁

1. 模板片段:可以讓我們引入一個寫好的html片段,相當於jsp:include功能了,比如頭部和尾部我們都一樣就可以復用,也可以引入一個頁面當做layout布局頁,以后的頁面都使用這個模板。

我們可以使用th:fragment來定義一個模板,使用th:insertth:replaceth:include來替換模板。

其中:

  • th:insert 3.0+版本新加的。
  • th:replace 2.0+ 3.0+都可用。
  • th:include 這個在3.0版本已經不建議使用。

這三個命令的語法格式為templatename::[domselector]。

我們先添加模板fragment/footer.html:

<html xmlns:th="http://www.thymeleaf.org">
<body>
    <span th:fragment="copyright">© 2019 <strong>xxx公司</strong></span>
</body>
</html>

home/index.html引用模板:

<!--th:include-->
<div th:include="fragment/footer :: copyright"></div>
<!--th:replace 直接替換-->
<div th:replace="fragment/footer :: copyright"></div>
<!--th:insert 把html插入到內部-->
<div th:insert="fragment/footer :: copyright"></div>

三個命令生成html結構如下,稍微有些不一樣:

2. 布局頁:設置一個母版頁,其他頁面以這個頁面做為母版,有父類的意思。

首先需要添加布局包依賴:

<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
    <version>2.2.2</version>
</dependency>

添加一個layout頁面(父頁面):

html代碼:

<!DOCTYPE html>
<html   xmlns:layout="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <header>這是頭部</header>
    <div layout:fragment="content"></div>
    <footer>這是底部</footer>
</body>
</html>

添加一個子頁面,以這個_home.html為父頁面:

其中:layout:decorator="_layout/_home" 指明布局頁的路徑,layout:fragment="content",指明要替換布局頁中的位置。

html代碼:

<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorator="_layout/_home">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div layout:fragment="content">
        這是child頁內容
    </div>
</div>
</body>
</html>

輸出:

四、總結

這次介紹了web開發的基本流程、包括靜態文件、模板引擎等,我們現在已經做好了web開發的准備工作,接下來就可以進行業務功能的編寫了,接下來我們會做一個簡單的CRUD來具體了解一下Web的基本流程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM