# Spring Boot 學習資源: https://spring.io/ 快速建立專案: https://start.spring.io/ ## 建立 Spring Boot 開發環境 ```java= package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication // @RestController 註解告訴Spring這段代碼描述了一個端點,該端點可以在web上運用。 @RestController public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } // hello() 我們添加的方法採用一個 value = name。 然後將此參數與單字結合。 // GetMapping("/hello") 告訴 Spring 使用我們的hello發送請求到 http://localhost:8080/hello // @RequestParam 告訴 Spring 再請求中期望一個名稱值,但如果不存在,它將默認使用單字 World。 @GetMapping("/hello") public String hello(@RequestParam(value = "name", defaultValue = "World") String name) { // %s 為 string return String.format("Hello %s!", name); } } ``` 使用以下指令來嘗試跑跑看Web ``` mvnw spring-boot:run ``` 成功跑起來!! ![](https://i.imgur.com/yrMVdVt.png) ## Springboot helloworld demoApplication.java ```java= package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { // Spring 應用啟動起來 SpringApplication.run(DemoApplication.class,args); } } ``` HelloController.java ```java= package com.example.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class HellController { @ResponseBody @RequestMapping("/hello") public String hello() { return "Hello World!"; } } ``` 成功執行的畫面 ![](https://i.imgur.com/mBjf0zY.png) ## 主程序類, 主入口類 (自動架構) 學習網站: https://www.youtube.com/watch?v=4t_xM7FefWM&list=PLmOn9nNkQxJEFsK2HVO9-WA55Z7LZ2N0S&index=8 @**SpringBootApplication**: Spring Boot 應用標住在某個類上說明這個類是Spring Boot的主配置類,SpringBoot就應該運行這個類的main方法啟動SpringBoot應用。 ```java= @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) ``` @SpringBootConfiguration: Spring Boot的配置類: - 標住在某個類上,表示這是一個Spring Boot配置類。 - @Configuration: 配置類上標註這個註解。 - 配置類 ----- 配置文件,配置類也是容器中的一個組件,@Componet @EnableAutoConfiguration: 開啟自動配置功能: - 以前我們需要配置的東西,Spring Boot幫我們自動配置, @EnableAutoConfiguration 告訴Spring Boot開啟自動配置功能,這樣配置才會生效。 @AutoConfigurationPackage: 自動配置包 - @Import({AutoConfigurationImportSelector.class}) - Spring的底層註解@Import,給容器中導入一個組件。導入的組件由AutoConfigurationExcludeFilter.class - 將主配置類(@SpringBootApplication標註的類)的所在包以及下面所有子包裡面所有組件掃描到Spring容器 ## 建立 RESTful Web 服務 參考網頁: https://spring.io/guides/gs/rest-service/ ```java= package com.example.demo; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.atomic.AtomicLong; @RestController public class GreetingController { private static final String template = "Hello, %s!"; private final AtomicLong counter = new AtomicLong(); // GetMapping("/hello") 確保 HTTP GET 請求到 /greeting 被映射到 greeting() 方法 // 也有很多種 HTTP 不同方式的請求例如: POST REQUEST.. // @PostMapping for POST 、 @RequestMapping(method=GET) for GET。 @GetMapping("/greeting") public Greeting greeting(@RequestParam(value = "name" , defaultValue = "World") String name) { return new Greeting(counter.incrementAndGet(),String.format(template,name)); } } ``` 好像是 8080 port有用過的關係,而網頁說的是沒有利用GetMapping映射。 ![](https://i.imgur.com/EoIa7nG.png) 在後來重開機之後,不知道為甚麼又成功跑出來了 ![](https://i.imgur.com/Y2RePp9.png) 測試服務: 網址: http://localhost:8080/greeting?name=user ![](https://i.imgur.com/aRSuuCc.png) 因為我在 Greeting.java 建立了一個 Greeting 的函式,而這個函式主要回傳 id 以及 字串 Greeting.java ```java= package com.example.demo; public class Greeting { private final long id; private final String content; public Greeting(long id, String content) { this.id = id; this.content = content; } public long getId() { return id; } public String getContent() { return content; } } ``` 而我在 GreetingController.java 回傳了 Greeting 的建構子,因此我的顯示內容會像蓋房子一樣當我 RequestParam 的 name 稍微更動,而我的 id 也會因此不同。 GreetingController.java ```java= package com.example.demo; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.atomic.AtomicLong; @SpringBootApplication @RestController public class GreetingController { private static final String template = "Hello, %s!"; private final AtomicLong counter = new AtomicLong(); // GetMapping("/hello") 確保 HTTP GET 請求到 /greeting 被映射到 greeting() 方法 // 也有很多種 HTTP 不同方式的請求例如: POST REQUEST.. // @PostMapping for POST 、 @RequestMapping(method=GET) for GET。 @GetMapping("/greeting") public Greeting greeting(@RequestParam(value = "name" , defaultValue = "World") String name) { return new Greeting(counter.incrementAndGet(),String.format(template,name)); } } ``` id 會一直增加因為會不斷新增新的 ID ![](https://i.imgur.com/wmZm2Yk.png) ![](https://i.imgur.com/N9NO0mG.png) ## Spring Boot 調用 Python腳本運行 學習網站: https://blog.csdn.net/qq_44648936/article/details/123593075 調用 Java Runtime.getRuntime() 方法,以達到成功執行 python 的檔案。 GreetingController.java ```java= package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.concurrent.atomic.AtomicLong; @RestController @RequestMapping("/face") public class GreetingController { @Autowired private FaceService faceService; @RequestMapping("/face") public void face() throws IOException { faceService.faceRecognition(); } } ``` FaceService.java ```java= package com.example.demo; import org.springframework.stereotype.Service; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @Service public class FaceService { // 前面一半是本地環境下的python的啟動文件地址, 後面一半是要執行的python腳本地址 public void faceRecognition() throws IOException { String[] arguments = new String[] {"C:\\\\Program Files (x86)\\\\Microsoft Visual Studio\\\\Shared\\\\Python36_64\\\\python.exe\"", "C:\\Users\\YouKlike\\Code\\Spring Boot\\main.py"}; Process process; try { process = Runtime.getRuntime().exec(arguments); // 執行py檔案 BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); new InputStreamReader(process.getInputStream()); String line = null; while ((line = in.readLine()) != null) { System.out.println(line); } in.close(); int re = process.waitFor(); System.out.println(re); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } } ``` 連線失敗Orz ![](https://i.imgur.com/WtLzk0S.png) 我猜應該是已經執行過了所以可能要重開機才能生效 ### SpringBoot Initializer 使用向導快速創建Spring Boot應用 IDE都支持使用Spring的項目創建向導快速創建一個Spring Boot項目 ### Spring Boot 配置 yaml簡介 - Spring Boot使用一個全局的配置文件,配置文件名是固定的: - application.properties - application.yml 配置文件的作用: 修改SpringBoot自動配置的默認值: SpringBoot在底層都給我們自動配置好了 YMAL (YMAL Ain't Markup Language) 標記語言: - 以前配置文件,大多都使用的是 xxx.xml文件: - YMAL