2021/06/26
2021/10/07 (更新內容)
2024/07/11 (更新內容)
Visual Studio Code跟Visual Studio是不一樣的,VS Code就像Eclipse或Visual Studio一樣,是個開發環境,不一樣的是,Eclipse很多功能都已經內建了,但是,VS Code是比較輕量級的開發環境,所以,很多功能都需要自己下載。要能夠執行Spring Boot要先安裝Java Development Kit (JDK) (建議java 17以上),另外,還需要安裝一些spring所需要的套件,請詳參Visual Studio Code裡的說明。
可利用指令確認目前已安裝之java版本
java -version
資料庫的部份,建議使用MySQL (詳參: http://www.codedata.com.tw/database/mysql-tutorial-getting-started/)。
Spring Framework是一個基於Java (J2EE)的MVC架構,也就是將一個web application分為模型層(Model)、展示層 (View)、控制層(Controller),通常Model中會有一般的類別或資料庫的存取邏輯,View則是與使用者的互動介面,Controller則是將Model與View串連起來的關鍵角色。過去是跟Struts、Hibernate並稱為SSH,然而,現在已經被Spring整合在一起,不再是三個不同的框架了。例如,Spring的Data JPA實作就是以Hibernate為基礎。不過,JPA用在相對複雜的資料表的存取還是多少有效率的問題,所以,越來越多人會盡量少用JPA。
Spring Boot簡化了Spring Framework的設定,因為Spring Boot內建伺服器,所以,不需要下載及安裝伺服器。
可以利用SPRING INITIALIZR產生一個空的spring boot專案,Project請選用Maven,Language選用Java,並使用Boot 3.3.1 (2024/07),Group: com.example,Artifact:demo,Packaging:Jar,Java版本: 17,Dependencies: Spring Web。範例裡的html是採用web,所以,如果沒有選web,還需要一些額外的設定。下載下來後,解壓縮在專案的檔案夾裡。
Maven vs Gradle: A Comprehensive Comparison for Spring Boot Developers (2023)
Maven is based on a POM file and is well-suited for smaller projects, while Gradle is more expressive and customizable, making it better suited for larger and more complex projects. Additionally, Gradle’s faster build times and support for incremental builds make it a better choice for Spring Boot projects.
如果使用Visual Studio Code,也可以利用Spring Initializr extension 產生新的spring boot專案 (詳參: Getting Started with Java in VS Code & Spring Boot in Visual Studio Code)。
如果使用Visual Studio Code,建議安裝Spring Boot Extension Pack,當專案越來越大的時候,這些extension會節省大家的時間,例如,其中的Spring Boot Dashboard for VS Code,可以列出所有的beans跟endpoints。
不管用哪個方法,都會產生一個空的專案,會有一個java檔: src/main/java/com/example/demo/DemoApplication.java,這是專案執行的起點。
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
一般而言,一個基本的java程式會有:
package com.example.demo;
public class DemoApplication {
public static void main(String[] args) {
}
}
在main裡面,利用SpringApplication.run來執行這個類別,並且將main收到的參數(args)傳遞給SpringApplication。基本上,執行這一行會啟動web server了。
SpringApplication.run(DemoApplication.class, args);
加了這一行,就必須加入對應的import。
package com.example.demo;
import org.springframework.boot.SpringApplication;
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
當我們加了@SpringBootApplication,Spring會自動scan這個這個package以下的目錄,所以,其他的檔案要放在com.example.demo下,或這在這個之下的目錄,如: com.example.demo.controller,(如: Structuring Your Code的建議)。
@在java中稱為Annotation,Annotation是java 5的新語法,雖然很多人將Annotation翻譯為註解,但是,Annotation跟Comment是完全不一樣的,Comment是純粹給人看的,而Annotation卻是給系統看的。當我們加了@SpringBootApplication,Spring boot會進行很多動作,例如:讀取一些設定檔,也會自動scan這個這個package以下的目錄,處理其他的Annotation (詳參: Spring Framework Annotations)。後面會看到更多的Annotation。在沒有Annotation之前,這些動作都必須靠很多的設定檔,現在這些動作都簡化了。
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Java annotation (wikipedia)
基本上去執行DemoApplication是沒有太多的意義,因為,並沒有定義任何的網頁或任何的服務,Spring是個MVC的架構,也就是會把程式碼切割為Model、View以及Controller。
過去,使用java開發網頁也是跟php差不多,執行每個程式(稱為servlet)就會產生對應的網頁,這樣的作法,雖然簡單,但是,當系統越來越大的時候就變得很複雜。後來,就有servlet+JSP的概念出現了,將html(view)與java為主的servlet切割。後來,系統越來越大,就跟php一樣,開始有一些框架的出現,一開始,是三個框架,稱為SSH(Spring、Struts、Hibernate),後來慢慢地整合在一起,成為現在的Spring。當框架出現時,首先就是提供最佳實務並且簡化設定,這些都是長期的累積前人的智慧,一步一步的演進到今天的規模。(手寫Servlet 到 Spring MVC 的簡化之路)
現在,在Spring裡,是利用Controller來定義所有的網路服務,服務有兩個部分:URI (URL)以及對應的HTTP action (如: Get, Post, Put, Delete)。
要定義一個Controller,首先,在DemoApplication.java的同一個目錄下,新增一個controller的資料夾,在資料夾中新增一個MainController.java。
一個最基本的Spring Controller就是一個類別,首先,會定義package,現在開始請養成習慣把同樣類型的類別都放在同一個package,例如,將controller都放在controller的package裡,並將檔案放在對應的路徑 (src/main/java/com/example/demo/controller)裡。
package com.example.demo.controller;
然後,import等一下需要的兩個類別。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
接下來,會利用java的Annotation:「@」告訴Spring boot定義這個類別是個Controller,spring boot會藉著這個annotation產生應該有的設定。
@Controller
一般而言,在@Controller裡會利用Mapping來設定被呼叫的方法及對應的URI。常用的HTTP 方法有get、post、put、patch、delete。
我們先指定index這個方法的為一個HTTP Get服務 ,在Spring 4.3之後,可利用GetMapping來也就是指定這個Controller是HTTP GET以及相對的URI,(在Spring 4.3之前,是使用@RequestMapping,詳參: Spring @RequestMapping New Shortcut Annotations)。
@ResponseBody,就是將指定內容(HTML)回傳給瀏覽器。
@GetMapping(value = "/")
@ResponseBody
下面的範例,就是告訴web server,當瀏覽器要求"/"時,就顯示Hi。
src/main/java/com/example/demo/controller/MainController.java。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController{
@GetMapping(value = "/")
@ResponseBody
public String index() {
return "<h1>Hi!</h1>";
}
}
在vs code下要執行這個專案,先選專案,再按左邊的Debug icon,在Debug menu下選:Debug (Launch)-DemoApplication
啟動後,在瀏覽器下打開:
http://localhost:8080
可以看到執行結果。
如果是希望去打開一個html檔案,就可以把@ResponseBody去掉,並把回傳內容改為檔案名稱。
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController{
@GetMapping(value = "/")
//@ResponseBody
public String index() {
return "index.html";
//return "<h1>Hi!</h1>";
}
}
index.html (src/main/resources/static/index.html)的內容,請注意,這個檔案不是放在controller的檔案夾裡。
<!DOCTYPE html>
<head lang="en">
<meta charset="UTF-8" />
<title>React with Spring REST</title>
</head>
<body>
<h1>HELLO</h1>
</body>
</html>
這邊就可以看到是把Controller跟View(網頁)分割了。只是,我們接下來不會使用網頁,而是利用react開發view。這樣的話,就不能只是使用單純的controller,而是進一步要使用REST Controller。
可以利用SPRING INITIALIZR產生一個空的spring boot專案,但無法找到對應的package。
DemoApplication.java:3: error: package org.springframework.boot does not exist
import org.springframework.boot.SpringApplication;
請安裝Spring Boot Extension Pack、Java Extension Pack。
如果看到
The import org.springframework.web cannot be resolved
應該就是在產生專案時,忘了選Spring Web。在VSCode裡,可以利用spring Initializr提供的功能來編輯,在pom.xml裡按右鍵,選擇"Edit Starter",就可以挑所需要的外掛,"Spring Web"。這樣的好處是,不會放錯地方。
也可以打開pom.xml,找到這一段
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
手動加上所需要的package
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>