Spring Boot 2.x (一):第一個 Web 應用 Hello Spring Boot 2
- 2019 年 11 月 6 日
- 筆記

一、開發環境
➜ ~ java -version java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
➜ ~ mvn -version Apache Maven 3.6.1
二、Spring Boot 簡介
Spring Boot 是由 Pivotal 團隊提供的全新框架,其設計目的是用來簡化新 Spring 應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Spring Boot致力於在蓬勃發展的快速應用開發領域(Rapid Application Development)成為領導者。
Spring Boot 具有以下特點:
- 可以創建獨立的 Spring 應用程式,並且基於 Maven 或 Gradle 插件,可以創建可執行的 JARs 和 WARs;
- 內嵌 Tomcat 或 Jetty 等 Servlet 容器;
- 提供自動配置的 「starter」 項目對象模型(POMS)以簡化 Maven 配置;
- 儘可能自動配置 Spring 容器;
- 提供一些常見的功能、如監控、WEB容器,健康,安全等功能;
- 絕對沒有程式碼生成,也不需要 XML 配置。
三、創建 Web 項目
3.1 首先啟動 Idea 找到 File -> New -> Project -> Spring Initializr

3.2 選擇 Next,填寫項目元資訊
- Group: 組織 ID,一般分為多個段,第一段為域,第二段為公司名稱。域又分為 org、com 或 cn 等等,其中 org 為非營利組織,com 為商業組織。
- Artifact: 唯一標識符,一般是項目名稱。

3.3 繼續選擇 Next,勾選項目依賴,這裡選擇 Web -> Spring Web

3.4 填寫項目名和項目路徑

3.5 最後選擇 Finish
此時第一個 Web 項目就創建完成了,對應的目錄結構如下:
├── HELP.md ├── chapter1.iml ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main │ ├── java │ │ └── com │ │ └── semlinker │ │ └── chapter1 │ │ └── Chapter1Application.java # 項目啟動類,包含main函數 │ └── resources │ ├── application.properties # 項目主要的配置文件 │ ├── static │ └── templates └── test └── java └── com └── semlinker └── chapter1 └── Chapter1ApplicationTests.java
此外在根目錄下還存在一個 pom.xml 文件,POM(Project Object Model,項目對象模型)是 Maven 工程的基本工作單元,是一個 XML 文件,包含了項目的基本資訊,用於描述項目如何構建,聲明項目依賴,等等。
執行任務或目標時,Maven 會在當前目錄中查找 POM。它讀取 POM,獲取所需的配置資訊,然後執行目標。
POM 中可以指定以下配置:
- 項目依賴
- 插件
- 執行目標
- 項目構建 profile
- 項目版本
- 項目開發者列表
- 相關郵件列表資訊
了解完 pom 相關的基礎知識,我們來一睹它的真容。打開項目中的 pom.xml
文件,該文件的具體內容如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.semlinker</groupId> <artifactId>chapter1</artifactId> <version>0.0.1-SNAPSHOT</version> <name>chapter1</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <!-- 項目依賴 --> <dependencies> <!-- 默認內嵌Tomcat容器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 測試依賴包,執行mvn package的時候,該包並不會被打入,因為它的生命周期只在test之內--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
說了那麼多,有些小夥伴估計已經按捺不住了,我們趕緊來啟動一下我們的第一個 Web 應用。

在運行 Chapter1Application 應用後,我們將在控制台看到 Spring Boot 的啟動資訊:
. ____ _ __ _ _ /\ / ___'_ __ _ _(_)_ __ __ _ ( ( )___ | '_ | '_| | '_ / _` | \/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |___, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.9.RELEASE) ... ... --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer: Tomcat started on port(s): 8080 (http) with context path '' --- [main] c.s.chapter1.Chapter1Application: Started Chapter1Application in 1.532 seconds (JVM running for 2.045)
通過觀察啟動資訊,我們可知 Spring Boot 默認使用 Tomcat 作為 Servlet 容器,且使用 8080 作為默認埠。小夥伴們是不是覺得入門 So easy,但當你在瀏覽器中訪問 http://localhost:8080/ 地址,你將會看到以下不忍直視的畫面:
Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Sat Oct 12 12:16:49 CST 2019 There was an unexpected error (type=Not Found, status=404). No message available
從 This application has no explicit mapping for /error
錯誤資訊中,可知是由於我們未設置 映射資訊導致的,下面我們來著手解決這個問題。要解決這個問題,我們需要新建一個 HelloController 類,在該類下定義請求映射資訊,具體如下:
package com.semlinker.chapter1.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/") public String greet() { return "Hello Spring boot 2.x"; } }
在完成 HelloController 類的定義之後,我們需要重新啟動一下應用。當應用成功啟動之後,我們再來使用瀏覽器來訪問一下 http://localhost:8080/ 地址,如果不出意外的話,我們將在頁面中看到預期的結果:
Hello Spring boot 2.x
四、常見問題
4.1 埠被佔用怎麼辦
通過前面的介紹,我們可知 Spring Boot 默認使用的埠是 8080,所以如果你們本地的 8080 埠已經被佔用了,那麼你將不能正常啟動 Spring Boot 項目。對於這個問題,我們可以通過一個簡單的方式來解決,即通過配置文件 application.properties 來修改默認的埠。
server.port=8088
當修改完配置文件,重啟應用的時候,在控制台可以看到以下的輸出資訊:
embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8088 (http)
這就表明我們已經成功修改了 Tomcat 默認的埠。
4.2 如何進行單元測試
細心的小夥伴可能會注意到在 chapter1 項目的根目錄下的 pom.xml 文件中還配置了一個依賴 —— spring-boot-starter-test:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
顧名思義,這個依賴就是為我們項目提供單元測試支援。
package com.semlinker.chapter1; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; import java.net.URL; import static org.junit.Assert.assertEquals; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class Chapter1ApplicationTests { @LocalServerPort private int port; @Autowired private TestRestTemplate template; @Test public void testGreet() { ResponseEntity<String> response = template.getForEntity("http://localhost:" + port, String.class); assertEquals(response.getBody(), "Hello Spring boot 2.x"); } }
在 Chapter1ApplicationTests 測試類中,我們通過注入 TestRestTemplate
對象,來發送 Http 請求。需要注意的是在使用 @SpringBootTest
註解時,需要設置 webEnvironment
屬性,否則運行單元測試時,會拋出異常,
詳細資訊可以參考 spring boot test unable to inject TestRestTemplate and MockMvc 這篇文章。
為了讓項目更加直觀,已對項目做了以下調整: Chapter1Application -> HelloSpringBoot2Application com.semlinker.chapter1 -> com.semlinker 項目地址:https://github.com/semlinker/springstack/tree/master/hello-springboot2