# 六角鼠年鐵人賽 Week 10 - Spring Boot - Build first API ==大家好,我是 "為了拿到金角獎盃而努力著" 的文毅青年 - Kai== ### 短歌行 曹操 :::info 對酒當歌,人生幾何!譬如朝露,去日苦多。 慨當以慷,憂思難忘。何以解憂?唯有杜康。 青青子衿,悠悠我心。但爲君故,沉吟至今。 呦呦鹿鳴,食野之苹。我有嘉賓,鼓瑟吹笙。 明明如月,何時可掇?憂從中來,不可斷絕。 越陌度阡,枉用相存。契闊談宴,心念舊恩。 月明星稀,烏鵲南飛。繞樹三匝,何枝可依? 山不厭高,海不厭深。周公吐哺,天下歸心。 ::: 上篇介紹過了 Spring Boot 的項目與優缺點,該篇就來手動建造個人的第一個 API 吧! 個人使用的工具為 **Intellij** 2019.03 community 版本,如果沒用過的人可以去下載來使用看看。 > **Intellij** 是 **JetBrain 公司** 專門為 Java 提供開發環境的 IDE,分作 **收費板(Ultimate)** 與 **免費版(Community)**。 >>JetBrain 開發了許多好用的 IDE,其中幾個著名的如: GoLand(GO語言)、 WebStorm(JavaScripts)、 PyCharm(Python) 等等,都是各領域工程師愛用的 IDE 收費版的功能十分強大,不過因為只是學習,我們只需要下載安裝 Community 版本就好,目前最新的 Version 是 2019.03 版。 [Intellij 官網](https://www.jetbrains.com/idea/) [Intellij IDE Download Page](https://www.jetbrains.com/idea/download/#section=windows) ## 建置第一個 Spring Boot 專案 我將使用 Gradle 方式進行建置,如果想用 Maven 的話,可自行選用習慣的方式建置。 ![](https://i.imgur.com/NsF8z93.png) 到如下圖的畫面後,輸入 or 更新 Name、GroupId 兩個欄位 Name: 專案名稱 GroupId: domain Name ![](https://i.imgur.com/xNO3PCO.png) 如果有遇到下面這張圖的問題,請不要擔心,這只是 Intellij 和 Windows Defender 之間的影響而已,直接選擇 Fix... 處理它 ![](https://i.imgur.com/ftssiRa.png) 點選 Configure Automatically ,接著應該會跳出一個確認視窗,點選 **是** 即可 ![](https://i.imgur.com/bCu0lwK.png) ## 調整 Gradle 設定 不免得我們還是要處理 Gradle 的設定來幫助我們安置要使用到的 Java 套件包 請打開 build.gradle 檔案 若有遇到如下圖的狀況,請選擇 Ok, apply suggestion! 這是 Gradle 在協助開發者處理 Gradle 相關服務的東西 (詳細可以查看gradle/wrapper/gradle-wrapper.properties 檔案中的設定) ![](https://i.imgur.com/qXXH5Ub.png) 接著我們開始調整 build.gradle 的設定: 1. 首先在 plugins 加入下列兩行,以取得 springboot 的框架套件 ``` id 'org.springframework.boot' version '2.2.0.RELEASE' id 'io.spring.dependency-management' version '1.0.8.RELEASE' ``` 若有出現下圖,請開心的點選 Enable Auto-Import,這樣未來 build.gradle 的更動 Intellij IDE 都會自動地幫你完成處理 ![](https://i.imgur.com/jvtkGHK.png) 2. 在 dependencies 中替換成以下內容,明確說明我們將使用的是 springboot starter web 的套件作開發,加上測試用的 JUnit 套件 ``` implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } ``` 3. 加入下面的內容,我們會去使用 JUnit Platform 幫助 ``` test { useJUnitPlatform() } ``` 4. 加入下面的指令,這樣等等我們就可以直接透過 Gradle 作測試執行,而不需要包成 Jar 檔 mainClassName 的內容視個人專案情況修正,主要是執行 Starter Class ``` apply plugin: 'application' mainClassName = 'kai.com.springbootApplicationStarter' ``` :::spoiler **完整 build.gradle 內容** ``` plugins { id 'java' id 'org.springframework.boot' version '2.2.0.RELEASE' id 'io.spring.dependency-management' version '1.0.8.RELEASE' } group 'kai.com' version '1.0-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } } test { useJUnitPlatform() } apply plugin: 'application' mainClassName = 'kai.com.springbootApplicationStarter' ``` ::: ## 創建 Spring Boot Starter Spring boot 會從標記 @SpringBootApplication 這個 annotation 的 Class 開始執行,每個Spring boot 專案都需要設定一個 Starter Class。 ==為求方便,Kai 自己稱呼其為 Starter,此不代表絕對名稱== ```java= package kai.com; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class springbootApplicationStarter { public static void main(String [] args){ SpringApplication.run(springbootApplicationStarter.class,args); } } ``` > 關於 @SpringBootApplication 其實際上包含了 @Configuration、@EnableAutoConfiguration、@ComponentScan 三個設定的功能。 > > 在 Spring boot 的專案中,只需要設定 @SpringBootApplication 即可。 ## 創建 API Controller 在這裡,我建立了兩個 Restful API,一個 GET 一個 POST,他們分別有不同取得參數的方式,在回傳部分,我會使用相同的 POJO Class 處理好,這樣方便我們檢視兩種方法的使用差異。 > @RestController 預設會回傳 application/json 格式的資料,如有需要可以調整 ```java= package kai.com.controller; import kai.com.bean.chatBean; import org.springframework.web.bind.annotation.*; @RestController public class chatController { @GetMapping("/chat") public chatBean chatting(@RequestParam(value = "username", defaultValue = "Unknowns") String username, @RequestParam(value = "content", defaultValue = "") String content) { String status = "Get By GET."; return new chatBean(username,content,status); } @PostMapping("/chat") public chatBean chatting2(@RequestBody chatBean cb) { String status = "Get By POST."; cb.setStatus(status); return cb; } } ``` ## 創建 POJO Bean 我們會創建一個用來存放資訊的 POJO 的 Bean Class,簡單的設計一個 username 和 content 以及告知的 status 就好。 我會在 call API 時候,將 username 和 content 預先放入 request 中,等程式取得這個 request 的時候,再塞入 status 值並返回這個 Bean,以便在取得回應時看到完整的 Bean 資訊。 ```java= package kai.com.bean; public class chatBean { private String username; private String content; private String status; public chatBean(String username, String content, String status){ this.username = username; this.content = content; this.status = status; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } } ``` ## 測試 打開最右邊的 Gradle 功能列表,進入 Tasks > application,點擊兩下 bootRun,Gradle 會開始進行 Project Compile,並在完成後直接執行。 ![](https://i.imgur.com/zU5tLHN.png) Kai 這邊使用 **SoapUI** 進行 call API 的測試,若是習慣其他如 Post Man 軟體的開發者也可以用自己習慣的軟體進行測試。 By GET 成功! ![](https://i.imgur.com/T6GfMbc.png) By POST 成功! ![](https://i.imgur.com/0Z575xl.png) ## Build Jar 完成開發與測試後就可以開始 Build Jar 了,雖然測試不是使用 JUnit... 這部分 Kai 想保留到後續專門介紹 JUnit 的時候再說。 打開 Gradle 功能列表,進入 Tasks > build,點擊兩下 build 執行建置。 ![](https://i.imgur.com/e6dojFn.png) 當建置完成後,便可在左方的專案列表中看到 build 資料夾與底下已建置好的 jar 檔和其他文檔。 ![](https://i.imgur.com/nI2u8HU.png) **springboot-first-api-1.0-SNAPSHOT.jar** 便是可以直接執行的 Jar 檔,且不需要放置在任何 Apache 底下即可獨立運行。 ## 結語 :::danger 以上內容就已經完成了一支簡單易懂的 Restful API 了。 下一篇將介紹 Lombok 套件 [六角鼠年鐵人賽 Week 11 - Spring Boot - Lombok 省時省力好幫手](/uWHqezBxQ9CPqr5iUOfNFQ?both) ::: 首頁 [Kai 個人技術 Hackmd](/2G-RoB0QTrKzkftH2uLueA) ###### tags: `Spring Boot`,`w3HexSchool`