1. 概述
Groovy 擁有我們在 Spring Web 應用程序中可以使用的多種功能。
因此,在本教程中,我們將使用 Spring Boot 和 Groovy 構建一個簡單的待辦事項應用程序。 此外,我們還將探索它們之間的集成點。
2. Todo 應用
我們的應用程序將具有以下功能:
- 創建任務
- 編輯任務
- 刪除任務
- 查看特定任務
- 查看所有任務
它將是一個基於 REST 架構 的應用程序,並且我們將使用 Maven 作為我們的構建工具。
2.1. Maven 依賴
讓我們在 pom.xml 文件中包含所有必需的依賴項:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy</artifactId>
<version>4.0.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>3.1.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
<scope>runtime</scope>
</dependency>在這裏,我們包括了 spring-boot-starter-web 以構建 REST 端點,並且導入了 groovy 依賴以為我們的項目提供 Groovy 支持。
對於持久層,我們使用 spring-boot-starter-data-jpa,並且 h2 是嵌入式數據庫。
此外,我們還需要包含 gmavenplus-plugin 及其所有 goals 在 pom.xml 中:
<build>
<plugins>
//...
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>compileTests</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>2.2. JPA 實體類
讓我們編寫一個簡單的 Todo groovy 類,包含三個字段:id、task 和 isCompleted:
@Entity
@Table(name = 'todo')
class Todo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id
@Column
String task
@Column
Boolean isCompleted
}在此,id字段是任務的唯一標識符。task包含任務的詳細信息,isCompleted則顯示任務是否已完成。
請注意,當我們未為字段提供訪問修飾符時,Groovy編譯器會將該字段設置為私有,並且會生成getter和setter方法。
2.3. 數據持久化層
讓我們創建一個 Groovy 接口 – TodoRepository – 並實現 JpaRepository。它將負責我們應用程序中的所有 CRUD 操作:
@Repository
interface TodoRepository extends JpaRepository<Todo, Integer> {}2.4 服務層
<strong><em>TodoService</em>接口包含所有用於我們CRUD操作的抽象方法:
interface TodoService {
List<Todo> findAll()
Todo findById(Integer todoId)
Todo saveTodo(Todo todo)
Todo updateTodo(Todo todo)
Todo deleteTodo(Integer todoId)
}TodoServiceImpl 是一個實現類,它實現了所有TodoService的方法:
@Service
class TodoServiceImpl implements TodoService {
//...
@Override
List<Todo> findAll() {
todoRepository.findAll()
}
@Override
Todo findById(Integer todoId) {
todoRepository.findById todoId get()
}
@Override
Todo saveTodo(Todo todo){
todoRepository.save todo
}
@Override
Todo updateTodo(Todo todo){
todoRepository.save todo
}
@Override
Todo deleteTodo(Integer todoId){
todoRepository.deleteById todoId
}
}2.5. 控制器層
現在,讓我們定義所有 REST API,這些 API 位於 TodoController 中,該控制器是我們的 @RestController。
@RestController
@RequestMapping('todo')
public class TodoController {
@Autowired
TodoService todoService
@GetMapping
List<Todo> getAllTodoList(){
todoService.findAll()
}
@PostMapping
Todo saveTodo(@RequestBody Todo todo){
todoService.saveTodo todo
}
@PutMapping
Todo updateTodo(@RequestBody Todo todo){
todoService.updateTodo todo
}
@DeleteMapping('/{todoId}')
deleteTodo(@PathVariable Integer todoId){
todoService.deleteTodo todoId
}
@GetMapping('/{todoId}')
Todo getTodoById(@PathVariable Integer todoId){
todoService.findById todoId
}
}這裏,我們定義了五個端點,用户可以調用它們來執行 CRUD 操作。
2.6. 啓動 Spring Boot 應用程序
現在,讓我們編寫一個包含主方法的類,用於啓動我們的應用程序:
@SpringBootApplication
class SpringBootGroovyApplication {
static void main(String[] args) {
SpringApplication.run SpringBootGroovyApplication, args
}
}請注意,在 Groovy 中,調用方法時傳遞參數時,使用括號是可選的——這也是我們在上面的示例中做的事情。
此外,對於 Groovy 中的任何類,後綴 .class 不需要,這也是為什麼我們直接使用 SpringBootGroovyApplication 的原因。
現在,讓我們在 pom.xml 中將其定義為 start-class:
<properties>
<start-class>com.baeldung.app.SpringBootGroovyApplication</start-class>
</properties>3. 運行應用程序
最後,我們的應用程序已準備好運行。只需將 SpringBootGroovyApplication 類作為 Java 應用程序運行,或運行 Maven 構建:
spring-boot:run這應該啓動應用程序,在 http://localhost:8080 上,並且我們應該能夠訪問其端點。
4. 測試應用程序
我們的應用程序已準備好進行測試。讓我們創建一個 Groovy 類 – TodoAppTest – 用於測試我們的應用程序。
4.1. 初始設置
讓我們在我們的類中定義三個靜態變量:<em >API_ROOT</em>、<em >readingTodoId</em> 和 <em >writingTodoId</em>。
static API_ROOT = "http://localhost:8080/todo"
static readingTodoId
static writingTodoId這裏,API_ROOT 包含我們的應用根 URL。 readingTodoId 和 writingTodoId 是我們測試數據的主鍵,我們將稍後使用它們進行測試。
現在,讓我們創建一個新的方法 – populateDummyData() ,通過使用註解 @BeforeClass 來填充測試數據:
@BeforeClass
static void populateDummyData() {
Todo readingTodo = new Todo(task: 'Reading', isCompleted: false)
Todo writingTodo = new Todo(task: 'Writing', isCompleted: false)
final Response readingResponse =
RestAssured.given()
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(readingTodo).post(API_ROOT)
Todo cookingTodoResponse = readingResponse.as Todo.class
readingTodoId = cookingTodoResponse.getId()
final Response writingResponse =
RestAssured.given()
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(writingTodo).post(API_ROOT)
Todo writingTodoResponse = writingResponse.as Todo.class
writingTodoId = writingTodoResponse.getId()
}我們還將填充變量——readingTodoId和writingTodoId,在同一方法中存儲我們正在保存的記錄的主鍵。
請注意,在 Groovy 中,我們還可以使用 帶有命名參數和默認構造函數的初始化 Bean,就像我們為readingTodo和writingTodo這樣的 Bean 所做的那樣,在上面的片段中。
4.2. 測試 CRUD 操作
接下來,讓我們從待辦事項列表中查找所有任務:
@Test
void whenGetAllTodoList_thenOk(){
final Response response = RestAssured.get(API_ROOT)
assertEquals HttpStatus.OK.value(),response.getStatusCode()
assertTrue response.as(List.class).size() > 0
}然後,我們通過傳遞 readingTodoId,來查找一個特定的任務:我們之前已經填充了這個值。
@Test
void whenGetTodoById_thenOk(){
final Response response =
RestAssured.get("$API_ROOT/$readingTodoId")
assertEquals HttpStatus.OK.value(),response.getStatusCode()
Todo todoResponse = response.as Todo.class
assertEquals readingTodoId,todoResponse.getId()
}在這裏,我們使用了 字符串插值來拼接URL字符串。
此外,讓我們通過使用 readingTodoId: 來更新待辦事項列表中的任務。
@Test
void whenUpdateTodoById_thenOk(){
Todo todo = new Todo(id:readingTodoId, isCompleted: true)
final Response response =
RestAssured.given()
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(todo).put(API_ROOT)
assertEquals HttpStatus.OK.value(),response.getStatusCode()
Todo todoResponse = response.as Todo.class
assertTrue todoResponse.getIsCompleted()
}然後,通過使用 writingTodoId,刪除待辦事項列表中的任務。
@Test
void whenDeleteTodoById_thenOk(){
final Response response =
RestAssured.given()
.delete("$API_ROOT/$writingTodoId")
assertEquals HttpStatus.OK.value(),response.getStatusCode()
}最後,我們可以保存一個新任務:
@Test
void whenSaveTodo_thenOk(){
Todo todo = new Todo(task: 'Blogging', isCompleted: false)
final Response response =
RestAssured.given()
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(todo).post(API_ROOT)
assertEquals HttpStatus.OK.value(),response.getStatusCode()
}5. 結論
在本文中,我們使用 Groovy 和 Spring Boot 構建了一個簡單的應用程序。我們還看到了它們如何集成在一起,並展示了 Groovy 的一些高級特性,並通過示例進行了説明。