知識庫 / Spring / Spring Boot RSS 訂閱

構建基於 Spring Boot 和 Groovy 的簡單 Web 應用程序

Groovy,Spring Boot
HongKong
7
01:00 PM · Dec 06 ,2025

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 及其所有 goalspom.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 類,包含三個字段:idtaskisCompleted

@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。 readingTodoIdwritingTodoId 是我們測試數據的主鍵,我們將稍後使用它們進行測試。

現在,讓我們創建一個新的方法 – 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()
}

我們還將填充變量——readingTodoIdwritingTodoId,在同一方法中存儲我們正在保存的記錄的主鍵。

請注意,在 Groovy 中,我們還可以使用 帶有命名參數和默認構造函數的初始化 Bean,就像我們為readingTodowritingTodo這樣的 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 的一些高級特性,並通過示例進行了説明。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.