快速學習 Spring Boot 技術棧

GitChat技術雜談發表於2017-11-28

文章推薦

Selenium 自動化測試從零實戰【原文連結】
原來這樣做,才能向架構師靠近【原文連結】
Cordova App 打包全揭祕【原文連結】
TensorFlow on Android:物體識別【原文連結】
TensorFlow on Android:訓練模式【原文連結】
圖解敏捷教練和 ScrumMaster【原文連結】
[運營專題]零預算引爆個人和企業品牌【原文連結】
學就會的 WordPress 實戰課【原文連結】

這裡寫圖片描述

作者簡介

純潔的微笑,曾經先後在網際網路金融、第三方支付公司擔任高階 Java 工程師、架構師、技術經理、技術負責人等職務。在網際網路金融工作期間,從零參與公司技術平臺建設,組織平臺進行過四次大架構升級。目前在一家第三方支付公司做架構師,負責支付公司大資料平臺建設。

課程簡介

如今微服務架構已經慢慢成為了網際網路架構的主流,Spring Boot 正是這股潮流的主先鋒。

本課程是圍繞 Spring Boot 技術棧的系列教程,目標是帶領讀者瞭解 Spring Boot 各種特性,學會使用 Spring Boot 相關技術棧上手開發專案。課程以 Spring Boot 所支援的技術棧為主線,一步一步瞭解每個組建的使用方式,最後綜合演練。

認真學完這個系列文章之後,會對 Spring Boot 有進一步的瞭解,具備使用 Spring Boot 上手進行開發的基本能力。

課程內容(前三課免費閱讀)

第01課:課程概要

第02課:快速實戰 Spring Boot

第03課:快速體驗 Web 開發

第04課:Spring Data JPA 的使用

第05課:模板引擎 Thymeleaf

第06課:JPA 和 Thymeleaf 實踐

第07課:Spring Boot 整合 MyBatis

第08課:MyBatis Druid 多資料來源

第09課:如何玩轉 Redis

第10課:Redis 實現資料快取和 Session 共享

第11課:RabbitMQ 詳解

第12課:MongoDB 實戰

第13課:使用 Spring Boot 傳送郵件

第14課:Spring Boot 整合 Quartz

第15課:Spring Boot 整合測試和部署運維

第16課:綜合實戰使用者管理系統

第01課:課程概要

背景

這個事情還要從 Spring 說起,2000 年左右 Java 行業中都是 EJB 的天下,但是 EJB 本身比較龐大複雜,各企業使用起來並不是很便利。有一個大神就站了出來,他就是 Rod Johnson。他認為企業開發應該更簡單,沒有必要全部使用 EJB,企業開發應該是一個統一的、高效的方式構造整個應用,並且可以將單層框架以最佳的組合揉和在一起建立一個連貫的體系。

於是在 2002 年編寫了一本書叫 《Expert One-to-One J2EE Design and Development ”(Wrox,2002)》,進一步的闡述了自己的思想。在這本書中,Rod Johnson 展示了他的 interface 21 框架,這一框架被髮布到開源世界後,組成了現在我們所知的 Spring 框架的基礎。接下來 Spring 發展迅速,平均兩三年就會釋出一個新版本,直到最近 9 月份推出的 Spring 5.0,Spring 也從一個小小的開源軟體發展為 Java 界第一個框架,覆蓋的內容也越來越廣泛。

Spring 在不斷髮展的過程中也出現了一些問題,隨著 Spring 邊界不斷擴張,需要的配置檔案也越來越多,使用起來也越複雜,專案中也經常因為配置檔案配置錯誤產生很多問題。慢慢 Spring 變成了一個大而全的框架,背離它簡潔開發的理念。Spring 也意識到了這些問題,急需有這麼一套軟體可以解決這些問題,這個時候微服務的概念也慢慢興起,Spring 站在了這麼一個高度上開發了一個全新的技術棧:Spring Boot。

Spring Boot 介紹

Spring Boot 是由 Pivotal 團隊提供的全新框架,其設計目的是用來簡化新 Spring 應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。採用 Spring Boot 可以大大的簡化開發模式,所有你想整合的常用框架,它都有對應的元件支援。

Spring Boot 是一套全新的框架,它來自於 Spring 大家族,因此 Spring 所有具備的功能它都有,而且更容易使用;Spring Boot 以約定大於配置的核心思想,預設幫我們進行了很多設定,多數 Spring Boot 應用只需要很少的 Spring 配置。Spring Boot 開發了很多的應用整合包,支援絕大多數開源軟體,讓我們以很低的成本去整合其他主流開源軟體。

Spring Boot 特性

  • 使用 Spring 專案引導頁面可以在幾秒構建一個專案
  • 方便對外輸出各種形式的服務,如 REST API、WebSocket、Web、Streaming、Tasks
  • 非常簡潔的安全策略整合
  • 支援關聯式資料庫和非關聯式資料庫
  • 支援執行期內嵌容器,如 Tomcat、Jetty
  • 強大的開發包,支援熱啟動
  • 自動管理依賴
  • 自帶應用監控
  • 支援各種 IED,如 IntelliJ IDEA 、NetBeans

熱度

Spring Boot 本身發展特別快,自從 2014 年 4 月釋出 Spring Boot 1.0 之後,版本更新非常頻繁,我在 2016 年使用的時候是 1.3.X,到現在 Spring Boot 最新穩定版本為 1.5.8,2.0 版本也進入了第 5 個里程碑。Spring Boot 一經推出就迅速的成為一門熱門的技術,從下圖也可以看出這個結論:
這裡寫圖片描述
enter image description here
此圖來自於百度指數,從圖中可知,自從 2015 年 6 月開始,Spring Boot 的搜尋指數呈穩定大幅增長的趨勢,說明大家對 Spring Boot 的關注度越來越高。
這裡寫圖片描述
enter image description here
此圖擷取於 Spring Boot 的首頁,可以看出 Spring 在官網重點推薦了三個專案,Spring Boot 排名第一,可見官方的重視程度。

為什麼學習 Spring Boot

  • 從軟體發展的角度來講,越簡單的開發模式越會流行。簡單的開發模式解放出更多生產力,讓開發人員可以將精力集中在業務上,而不是各種配置、語法所設定的門檻上。Spring Boot 就是儘可能的簡化應用開發的門檻。

  • Spring Boot 所整合的技術棧,幾乎都是各網際網路公司在使用的技術,按照 Spring Boot 的路線去學習,基本可以瞭解國內外網際網路公司的技術特點。

  • Spring Boot 和微服務架構都是未來軟體開發的一個大趨勢,越早參與其中受益越大。

這個課程可以學到什麼

早些時候由於工作原因研究並使用了 Spring Boot,在使用時發現,國內對於 Spring Boot 介紹的資料並不是很多,網上充斥著各種資料質量參差不齊,這給初學者帶來了很大的困擾。於是我在網路上連載了 Spring Boot 的系列文章,並且受到廣大網友的喜歡。早期的文章可以在我的個人公眾號或者部落格檢視:

回過頭來再次翻看這些文章,很多的 API 已經過時,大多數文章也只是理論為主,並且那時候對 Spring Boot 沒有一個整體的瞭解,文章只是羅列了最基本的使用。因此我又重新梳理了 Spring Boot 技術棧,將其中工作中最常用、最具實戰代表性的一些內容重新整理出來,以 GitChat 達人課的形式來展現。課程也增加了實戰專案的內容,讓你親自體會如何使用 Spring Boot 技術棧進行快速開發,並且可以很快的應用在工作中。

本期達人課,首先介紹如何使用 Spring Boot 進行快速開發,再一起探討 Spring Boot 如何快速整合主流開源軟體,最後使用 Spring Boot 技術棧實現一個簡單的使用者管理系統,進行實戰演練。通過本課程學習,可以掌握工作中最常用的技術和實際專案的使用經驗。

適合閱讀的人群

該系列文章適合以下人群閱讀:

  • 從事 Java 相關開發對 Spring Boot 感興趣的人員
  • 傳統開發領域,急迫想打破原有開發模式的開發人員

在學習本節課程之前,首先需要了解 Spring、Maven 和其他開源軟體的基礎技能。

因為 Spring Boot 2.0 還在開發中,為了更貼近實戰,我們選取 Spring Boot1.5.8.RELEASE 版本進行演示。

開發環境:

  • IDEA 2017
  • JDK 1.8

使用到的軟體:

  • JPA
  • MyBatis
  • Thymeleaf
  • Druid
  • Redis
  • RabbitMQ
  • MongoDB
  • Quartz

課程列表

  • 快速實戰 Spring Boot
  • 快速體驗 Web 開發
  • Spring Data JPA 的使用
  • 前端模板引擎 Thymeleaf
  • JPA 和 Thymeleaf 實踐
  • Spring Boot 整合 MyBatis
  • MyBatis Druid 多資料來源
  • 如何玩轉 Redis
  • Redis 實現 Session 共享
  • RabbitMQ 詳解
  • MongoDB 實戰
  • 使用 Spring Boot 傳送郵件
  • Spring Boot 整合 Quartz
  • Spring Boot 整合測試和部署運維
  • 綜合實戰使用者管理系統

點選這裡下載原始碼

第02課:快速實戰 Spring Boot

什麼是 Spring Boot

Spring 在官方首頁這樣介紹:

BUILD ANYTHING . Spring Boot is designed to get you up and running as quickly as possible, with minimal upfront configuration of Spring. Spring Boot takes an opinionated view of building production ready applications.

解釋一下:Spring Boot 可以構建一切。Spring Boot 設計之初就是為了最少的配置,最快的速度來啟動和執行 Spring 專案。Spring Boot 使用特定的配置來構建生產就緒型的專案。

使用 Spring Boot 有什麼好處

其實就是簡單、快速、方便!如果搭建一個 Spring Web 專案的時候需要怎麼做呢?

  • 配置 web.xml,載入 Spring 和 Spring MVC
  • 配置資料庫連線、配置 Spring 事務
  • 載入配置檔案的讀取,開啟註解
  • 配置日誌檔案
  • 配置完成之後部署 Tomcat 除錯

現在非常流行微服務,如果我這個專案僅僅只是需要傳送一個郵件,如果我的專案僅僅是生產一個積分;我都需要這樣折騰一遍!

但是如果使用 Spring Boot 呢?很簡單,僅僅只需要三步就可以快速的搭建起一個 Web 專案!

使用 Spring Boot 到底有多爽,用下面這幅圖來表達:
這裡寫圖片描述

快速入門

說了那麼多,手癢癢的很,馬上來一發試試!

構建專案

(1)訪問 http://start.spring.io/

(2)選擇構建工具 Maven Project、Spring Boot 版本 1.5.8 及一些工程基本資訊,可參考下圖:
這裡寫圖片描述

(3)單擊 Generate Project 按鈕並下載專案壓縮包。

(4)解壓後,單擊 Eclipse,Import | Existing Maven Projects | Next | 選擇解壓後的資料夾 | Finsh 命令,OK Done!

(5)如果使用的是 Idea,單擊 File | New | Model from Existing Source.. | 選擇解壓後的資料夾 | OK 命令, 選擇 Maven ,一路 Next,OK Done!

如果讀者使用的是 Idea 工具,也可以這樣:

(1)單擊 File | New | Project… 命令,彈出新建專案框。

(2)選擇 Spring Initializr 選項,單擊 Next 按鈕,也會出現上述類似的配置介面,Idea 幫我們做了整合。

(3)填寫相關內容後,單擊 Next 按鈕,選擇依賴的包再單擊 Next 按鈕,最後確定資訊無誤單擊 Finish 按鈕。

對上面的配置做一個解釋:

  • 第一個選擇框選擇建立以 Maven 構建專案,還是以 Gradle 構建專案,這是兩種不同的構建方式,其中 Gradel 配置內容更簡潔一些,並且包含了 Maven 的使用,不過日常使用 Maven 居多。
  • 第二個選擇框選擇程式語言,現在支援 Java、Kotlin 和 Groovy。
  • 第三個選擇框選擇 Spring Boot 版本,可以看出 Spring Boot 2.0 已經到了第五個里程碑了。在實際使用中,我們會優先使用穩定版本,1.0 的最新穩定版本是 1.5.8,也是我們演示使用的版本。

下面就是專案的配置資訊了。

  • Group:一般填寫公司域名,比如百度公司填 com.baidu,演示使用 com.neo。
  • Artifact:可以理解為專案的名稱,可以根據實際情況來填,本次演示填寫 helloWorld。
  • Dependencies:在這塊新增我們專案所依賴的 Spring Boot 元件,可以多選。本次選擇 Web、devtools 兩個模組。
    專案結構介紹

這裡寫圖片描述

如上圖所示,Spring Boot 的基礎結構共三個檔案:

  • src/main/java:程式開發以及主程式入口
  • src/main/resources:配置檔案
  • src/test/java:測試程式

另外,Sping Boot 建議的目錄結果如下:

root package 結構:com.example.myproject

myproject
 +-src
    +- main
         +- java
              +- com.example.myproject
                    +- comm
                    +- domain
                    +- repository
                    +- service
                    +- web
                    +- Application.java
         +- resources
              +- static
              +- templates
              +- application.properties
    +- test
 +-pom.xml

com.example.myproject 目錄下:

  • Application.java:建議放到根目錄下面,是專案的啟動類,Spring Boot 專案只能有一個 main() 方法。
  • comm:目錄建議放置公共的類,如全域性的配置檔案、工具類等。
    domain:目錄主要用於實體(Entity)與資料訪問層(Repository)。
  • repository:資料庫訪問層程式碼。
  • service:該層主要是業務類程式碼。
  • web:該層負責頁面訪問控制。

resources 目錄下:

  • static:目錄存放 Web 訪問的靜態資源,如 JS、CSS、圖片等。
    templates:目錄存放頁面模板。
  • application.properties:專案的配置資訊。
  • test 目錄存放單元測試的程式碼;pom.xml 用於配置專案依賴包,以及其他配置。

採用預設配置可以省去很多設定,當然也可以根據自己的喜好來進行更改。最後,啟動 Application main 方法,至此一個 Java 專案搭建好了!

簡單 Web 開發

(1)可以在 Spring Initializr 上面新增,也可以手動在 pom.xml 中新增:

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

pom.xml 檔案中預設有兩個模組:

  • spring-boot-starter:核心模組,包括自動配置支援、日誌和 YAML;

  • spring-boot-starter-test:測試模組,包括 JUnit、Hamcrest、Mockito。

(2)編寫 controller 內容:

@RestController
public class HelloWorldController {

    @RequestMapping("/hello")
    public String hello() {
        return "Hello World";
    }
}

@RestController的意思就是 controller 裡面的方法都以 json 格式輸出,不用再配置什麼 jackjson 的了!

如果配置為@Controller就代表著輸出為頁面內容。

(3)啟動主程式,開啟瀏覽器訪問 http://localhost:8080/hello,就可以看到以下內容,是不是很簡單!

Hello World
(4)如果我們想傳入引數怎麼辦?

@RestController
public class HelloWorldController {

    @RequestMapping("/hello")
    public String index(String name) {
        return "Hello World, " +name;
    }
}

重新啟動專案,訪問 http://localhost:8080/hello?name=neo,返回內容如下:

Hello World,neo

經過上一個測試發現,修改 controller 內相關程式碼,就需要重新啟動專案才能生效,這樣做很麻煩是不是,彆著急。Spring Boot 提供了另外一個元件來解決。

熱部署

熱啟動就需要用到我們在一開始引入的另外一個元件:devtools。它是 Spring Boot 提供的一組開發工具包,其中就包含我們需要的熱部署功能。但是在使用這個功能之前還需要再做一些配置。

(1)在 dependency 中新增 optional 屬性,並設定為 true:

 <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

(2)在 plugin 中配置另外一個屬性 fork,並且配置為 true:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <fork>true</fork>
            </configuration>
        </plugin>
</plugins>
</build>

OK,以上兩步配置完成,如果讀者使用的是 Eclipse,那麼恭喜你大功告成了。

如果讀者使用的是 Idea 還需要做以下配置。

(3)配置 Idea

選擇 File-Settings-Compiler 勾選 Build project automatically,低版本 Idea 勾選make project automatically
這裡寫圖片描述

使用快捷鍵:CTRL + SHIFT + A 輸入Registry 找到選項 compile.automake.allow.when.app.running 勾選

這裡寫圖片描述

全部配置完成後,Idea 就支援熱部署了,大家可以試著去改動一下程式碼就會發現 Spring Boot 會自動重新載入,再也不需要我們手動點選重新部署了。

為什麼 Idea 需要多配置後面這一步呢,因為 Idea 預設不是自動編譯的,需要我們手動去配置後才會自動編譯,而熱部署依賴於專案的自動編譯功能。

該模組在完整的打包環境下執行的時候會被禁用。如果使用 java -jar 啟動應用或者用一個特定的 classloader 啟動,它會認為這是一個“生產環境”。

單元測試

單元測試在日常開發中是必不可少的,一個牛逼的程式設計師,單元測試寫得也是槓槓的。下面來看下 Spring Boot 對單元測試又做了哪些支援?

如果我們只想執行一個 hello World,只需要一個註解就可以。在 src/test 目錄下新建一個 HelloTests 類,程式碼如下:

public class HelloTest {
    @Test
    public void hello(){
        System.out.println("hello world");
    }
}

單擊右鍵“執行”按鈕,會發現控制檯輸出:hello world。僅僅只需要了一個註解。但是如果我們需要測試 web 層的請求呢?Spring Boot 也給出了支援。

以往我們在測試 web 請求的時候,需要手動輸入相關引數在頁面測試檢視效果,或者自己寫 post 請求。在 Spring Boot 中,Spring 給出了一個簡單的解決方案;使用 mockmvc 進行 web 測試,mockmvc 內建了很多工具類和方法,可以模擬 post、get 請求,並且判斷返回的結果是否正確等,也可以利用print()列印執行結果。

@SpringBootTest
public class HelloTest {

    private MockMvc mockMvc;

    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
    }

    @Test
    public void getHello() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.post("/hello?name=小明").accept(MediaType.APPLICATION_JSON_UTF8)).andDo(print());
    }

}

在類的上面新增@SpringBootTest,系統會自動載入 Spring Boot 容器。在日常測試中,我們就可以注入 bean 來做一些區域性業務的測試。MockMvcRequestBuilders可以 post、get 請求,使用print()方法會將請求和相應的過程都列印出來,如下:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /hello
       Parameters = {name=[neo]}
          Headers = {}

Handler:
             Type = com.neo.helloWorld.web.HelloWorldController
           Method = public java.lang.String com.neo.helloWorld.web.HelloWorldController.hello(java.lang.String)

...

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[text/plain;charset=ISO-8859-1], Content-Length=[16]}
     Content type = text/plain;charset=ISO-8859-1
             Body = Hello World ,neo
    Forwarded URL = null
   Redirected URL = null
          Cookies = []   

從返回的Body = Hello World ,neo可以看出請求成功。

總結

使用 Spring Boot 可以非常方便、快速搭建專案,而不用關心框架之間的相容性、適用版本等各種問題,我們想使用任何東西,僅僅新增一個配置就可以,所以使用 Sping Boot 非常適合構建微服務。

建議大家使用 Idea 開發 Spring Boot 專案,Eclipse 對 Spring Boot 專案支援並不好,並且使用 Eclipse 偶爾會出現一些詭異的問題,影響初學者的學習。

點選這裡下載原始碼。

第03課:快速體驗 Web 開發

本篇介紹 Spring Boot 對 Web 開發的支援。

從上篇文章可知,Spring Boot 對 Web 開發做了很大的優化,包括開發、測試、部署都做了支援。本篇內容介紹 Spirng Boot 對 Web 提供的其他便利。

spring-boot-starter-web 是 Spring Boot 對 Web 開發的支援,主要包括 RESTful、引數校驗、使用 Tomcat 作為內嵌容器等功能,接下來一一介紹。

Json 的支援

在 Spring Boot 體系中,天然對 Json 支援,在上篇文章中給大家做了簡單的演示,這次來深入使用一番。

新建一個專案 spring-boot-web,新增上篇同樣的元件依賴,匯入專案到 Idea 中。在專案路徑下新建 domain 包,在包下新建一個實體類 User,User 資訊如下:

public class User {
    private String name;
    private int age;
    private String pass;
    //setter、getter 省略
}

在專案中新建 web 包,並在 web 包下新建一個類 WebController,在類中建立一個方法返回 User,如下:

@RestController
public class WebController {
    @RequestMapping("/getUser")
    public User getUser() {
        User user=new User();
        user.setName("小明");
        user.setAge(12);
        user.setPass("123456");
        return user;
    }
}

在 Test 包下新建 WebControllerTest 測試類,對 getUser() 方法進行測試。

@SpringBootTest
public class WebControllerTest {
    //省略部分程式碼
    @Test
    public void getUser() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.post("/getUser")).andDo(print());
    }

}

返回結果如下:

{"name":"小明","age":12,"pass":"123456"}

說明 Spring Boot 自動將 User 物件轉成了 Json 進行返回。那麼如果返回的是一個 list 呢,在 WebController 新增方法 getUsers():

 @RequestMapping("/getUsers")
    public List<User> getUsers() {
        List<User> users=new ArrayList<User>();
        User user1=new User();
        user1.setName("neo");
        user1.setAge(30);
        user1.setPass("neo123");
        users.add(user1);
        User user2=new User();
        user2.setName("小明");
        user2.setAge(12);
        user2.setPass("123456");
        users.add(user2);
       return users;
    }

新增測試方法進行測試,返回內容如下:

[{"name":"neo","age":30,"pass":"neo123"},{"name":"小明","age":12,"pass":"123456"}]

說明不管是物件還是集合或者物件巢狀,Spring Boot 均可以將其轉化為 Json 字串,特別適合我們給其他系統提供介面時使用。

請求傳參

使用 Spirng Boot 可以輕鬆的對請求做一些限制,比如為了安全只允許 POST 請求的訪問。只需要在方法上新增一個配置即可:

@RequestMapping(name="/getUser", method= RequestMethod.POST)
public User getUser() {
    ...
}

這時候再以 get 請求去訪問,就會返回:Request method 'GET' not supported

Spring Web 層支援多種方法傳參,上篇文章中傳入一個屬性 name,其直接使用物件接收也是支援的。

@RequestMapping(name="/getUser", method= RequestMethod.POST)
public String getUser(User user) {
    ...
}

這樣的寫法,只要是 User 的屬性都會被自動填充到 user 物件中。還有另外一種傳參的方式。

使用 Url 進行傳參,這種形式的傳參位址列會更加美觀一些。

@RequestMapping(value="get/{name}", method=RequestMethod.GET)
public User get(@PathVariable String name) {
    User user=new User();
    user.setName(name);
    return user;
}

瀏覽器訪問:http://localhost:8080/get/neo,返回:{"name":"neo","age":0,"pass":null},說明 name 值已經傳入成功。

引數校驗

引數校驗在我們日常開發中非常常見,最基本的校驗有判斷屬性是否為空、長度是否符合要求等,在傳統的開發模式中需要寫一堆的 if else 來處理這些邏輯,很繁瑣,效率也低。使用 @Valid + BindingResult 就可以優雅地解決這些問題,接下來看看示例:

首先在 WebController 新增一個儲存使用者的方法 saveUser,引數為 User,現在需要對引數 User 做校驗:

public class User {
    @NotEmpty(message="姓名不能為空")
    private String name;
    @Max(value = 100, message = "年齡不能大於 100 歲")
    @Min(value= 18 ,message= "必須年滿 18 歲!" )
    private int age;
    @NotEmpty(message="密碼不能為空")
    @Length(min=6,message="密碼長度不能小於 6 位")
    private String pass;

    //...
}

對不同的屬性,按照規則新增了不同校驗內容。

Spring Boot 的引數校驗其實是依賴於 hibernate-validator 來進行。現在模擬對引數 User 進行引數校驗,使用 @Valid + BindingResult,校驗後如果有錯誤將錯誤列印出來,程式碼如下:

@RequestMapping("/saveUser")
public void saveUser(@Valid User user,BindingResult result) {
    System.out.println("user:"+user);
    if(result.hasErrors()) {
        List<ObjectError> list = result.getAllErrors();
        for (ObjectError error : list) {
            System.out.println(error.getCode() + "-" + error.getDefaultMessage());
        }
    }
}

新增測試方法進行測試:

@Test
public void saveUsers() throws Exception {
    mockMvc.perform(MockMvcRequestBuilders.post("/saveUser")
            .param("name","")
            .param("age","666")
            .param("pass","test")
    ).andDo(print());
}

結果返回:

user:name=,age=666,pass=test
Max-年齡不能大於 100Length-密碼長度不能小於 6 位
NotEmpty-姓名不能為空

結果顯示均已經觸發了校驗規則,返回了錯誤資訊,在實際使用過程中可以對錯誤資訊進行包裝,最後返回到前端進行展示。

自定義 Filter

我們常常在專案中會使用 Filters 用於記錄請求日誌、排除有 XSS 威脅的字元、執行許可權驗證等等。Spring Boot 自動新增了 OrderedCharacterEncodingFilter 和 HiddenHttpMethodFilter,並且可以自定義 Filter。

自定義 Filter 兩個步驟:

實現 Filter 介面,實現 Filter 方法 新增@Configuration 註解,將自定義 Filter 加入過濾鏈

新建 MyFilter 類,使用 doFilter() 方法:

public class MyFilter implements Filter {
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        HttpServletRequest request = (HttpServletRequest) srequest;
        System.out.println("this is MyFilter,url :"+request.getRequestURI());
        filterChain.doFilter(srequest, sresponse);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }
}

將自定義 Filter 加入過濾鏈:

@Configuration
public class WebConfiguration {
    @Bean
    public RemoteIpFilter remoteIpFilter() {
        return new RemoteIpFilter();
    }

    @Bean
    public FilterRegistrationBean testFilterRegistration() {

        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new MyFilter());
        registration.addUrlPatterns("/*");
        registration.addInitParameter("paramName", "paramValue");
        registration.setName("MyFilter");
        registration.setOrder(1);
        return registration;
    }
}

新增完後啟動專案,訪問任意的 Url,都會看到控制檯列印如下資訊:

this is MyFilter,url :/xxx

說明 MyFilter 已經對所有的 Url 進行了監控,在實際使用的過程中,常常利用這個特性進行 session 驗證,判斷使用者是否登入。

自定義 Property

在 Web 開發的過程中,經常需要自定義一些配置檔案,如何使用呢?

配置在 application.properties 中

com.neo.title=純潔的微笑
com.neo.description=分享生活和技術

自定義配置類:

@Component
public class NeoProperties {
    @Value("${com.neo.title}")
    private String title;
    @Value("${com.neo.description}")
    private String description;

    //省略 getter settet 方法

    }

寫單元測試進行驗證:

@RunWith(SpringRunner.class)
@SpringBootTest
public class PropertiesTest {

    @Resource
    private NeoProperties properties;

    @Test
    public void testProperties() throws Exception {
        System.out.println("title:"+properties.getTitle());
        System.out.println("description:"+properties.getDescription());
    }

}

執行 test 後輸出結果:

text title:純潔的微笑 description:分享生活和技術

如果測試中出現中文亂碼,可安裝以下方法進行設定:

依次單擊 File | Settings | Editor | File Encodings 命令,將 Properties Files (*.properties) 下的 Default encoding for properties files 設定為 UTF-8,將 Transparent native-to-ascii conversion 前的核取方塊勾選上。

總結

Spring Boot 整合了引數校驗、內嵌容器、Restful、JSON 內容,這些技術在進行 Web 開發中必不可少。Spring Boot 對這些技術進行了包裝,讓我們在 Web 專案開發過程中非常容易的使用這些技術,降低了開發 Web 專案的技術難度。

點選這裡下載原始碼

下一篇

相關文章