1. Обзор
Groovy имеет ряд возможностей, которые мы, возможно, захотим использовать в наших весенних веб-приложениях.
Итак, в этом уроке мы создадим простое приложение для выполнения задач с помощью Spring Boot и Groovy. Кроме того, мы рассмотрим их точки интеграции.
2. Приложение Todo
Наше приложение будет иметь следующие функции:
- Создать задачу
- Задача редактирования
- Удалить задачу
- Просмотр конкретной задачи
- Просмотр всех задач
Это будет приложение на основе REST , и мы будем использовать Maven в качестве инструмента сборки .
2.1. Зависимости Maven
Давайте включим все необходимые зависимости в ваш pom.xml файл:
org.springframework.boot spring-boot-starter-data-jpa 2.4.0 org.springframework.boot spring-boot-starter-web 2.4.0 org.codehaus.groovy groovy 3.0.3 org.springframework.boot spring-boot-starter-test 2.4.0 test com.h2database h2 1.4.200 runtime
Здесь мы включаем spring-boot-starter-web для создания конечных точек REST и импортируем зависимость groovy для обеспечения поддержки Groovy для нашего проекта .
Для уровня персистентности мы используем spring-boot-starter-data-jpa , а h2 – это встроенная база данных .
Кроме того, мы должны включить gmavenplus-плагин со всеми целями в pom.xml:
//... org.codehaus.gmavenplus gmavenplus-plugin 1.9.0 addSources addTestSources generateStubs compile generateTestStubs compileTests removeStubs removeTestStubs
2.2. Класс сущностей JPA
Давайте напишем простую Todo Класс Groovy с тремя полями – id , задача, и завершена :
@Entity @Table(name = 'todo') class Todo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Integer id @Column String task @Column Boolean isCompleted }
Здесь поле id является уникальным идентификатором задачи. задача содержит сведения о задаче и завершена показывает, завершена ли задача или нет.
Обратите внимание, что, когда мы не предоставляем модификаторы доступа к полю, компилятор Groovy сделает это поле закрытым, а также создаст для него методы getter и setter .
2.3. Уровень Персистентности
Давайте создадим классный интерфейс – TodoRepository , который реализует JpaRepository . Он позаботится обо всех операциях CRUD в нашем приложении:
@Repository interface TodoRepository extends JpaRepository{}
2.4. Уровень Обслуживания
Интерфейс To do Service содержит все абстрактные методы, необходимые для нашей работы с CRUD :
interface TodoService { ListfindAll() Todo findById(Integer todoId) Todo saveTodo(Todo todo) Todo updateTodo(Todo todo) Todo deleteTodo(Integer todoId) }
TodoServiceImpl – это класс реализации , который реализует все методы To do Service:
@Service class TodoServiceImpl implements TodoService { //... @Override ListfindAll() { 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. Уровень Контроллера
Теперь давайте определим все API REST в TodoController , который является нашим @RestController :
@RestController @RequestMapping('todo') public class TodoController { @Autowired TodoService todoService @GetMapping ListgetAllTodoList(){ 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 использование круглых скобок необязательно при вызове метода путем передачи аргументов – и это то, что мы делаем в приведенном выше примере.
Кроме того, суффикс . class не нужен для любого класса в Groovy вот почему мы используем приложение Spring Boot Groovy напрямую.
Теперь давайте определим этот класс в pom.xml как начальный класс :
com.baeldung.app.SpringBootGroovyApplication
3. Запуск приложения
Наконец, наше приложение готово к запуску. Мы должны просто запустить приложение Spring Boot Groovy класс в качестве приложения Java или запустить сборку Maven:
spring-boot:run
Это должно запустить приложение на http://localhost:8080 и мы должны иметь доступ к его конечным точкам.
4. Тестирование приложения
Наше приложение готово к тестированию. Давайте создадим классный класс – TodoAppTest для тестирования нашего приложения.
4.1. Начальная настройка
Давайте определим три статические переменные – API_ROOT , readingTodoId, и writingTodoId в нашем классе:
static API_ROOT = "http://localhost:8080/todo" static readingTodoId static writingTodoId
Здесь/| API_ROOT содержит корневой URL-адрес нашего приложения. чтение для выполнения Id и запись для выполнения Id являются первичными ключами наших тестовых данных, которые мы будем использовать позже для выполнения тестирования.
Теперь давайте создадим другой метод – 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 мы также можем инициализировать бобы с помощью именованных параметров и конструктора по умолчанию , как мы делаем для бобов, таких как readingTodo и writingTodo в приведенном выше фрагменте.
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 }
Затем давайте найдем конкретную задачу, передав reading To do Id , которую мы заполнили ранее:
@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-адреса.
Кроме того, давайте попробуем обновить задачу в списке задач с помощью reading To do Id :
@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() }
А затем удалите задачу из списка задач, используя writing To do Id :
@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 на примерах.
Как всегда, полный исходный код примера доступен на GitHub .