Урок 50: Итоговый проект
В этом заключительном уроке курса мы создадим полноценное веб-приложение, которое объединяет все изученные нами концепции. Это будет комплексный проект, включающий базу данных, веб-интерфейс и RESTful API. Мы будем использовать Spring Boot для создания серверной части, Hibernate для взаимодействия с базой данных и Thymeleaf для рендеринга HTML-страниц.
Структура проекта
Наше приложение будет включать следующие компоненты:
- База данных: Мы будем использовать базу данных H2 для хранения данных о пользователях и задачах.
- RESTful API: Приложение будет предоставлять API для управления пользователями и задачами.
- Веб-интерфейс: Приложение будет включать веб-интерфейс для отображения и управления данными.
Создание базы данных
Для начала настроим базу данных H2. Добавьте следующую конфигурацию в файл application.properties
:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
Модели данных
Создадим классы моделей для пользователей и задач:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String email;
// Getters and setters
}
@Entity
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String description;
private boolean completed;
// Getters and setters
}
Репозитории
Создадим интерфейсы репозиториев для взаимодействия с базой данных:
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Long> {
}
public interface TaskRepository extends CrudRepository<Task, Long> {
}
RESTful API
Создадим контроллеры для управления пользователями и задачами:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping
public Iterable<User> getUsers() {
return userRepository.findAll();
}
@PostMapping
public User createUser(@RequestBody User user) {
return userRepository.save(user);
}
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userRepository.findById(id).orElse(null);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userRepository.deleteById(id);
}
}
@RestController
@RequestMapping("/api/tasks")
public class TaskController {
@Autowired
private TaskRepository taskRepository;
@GetMapping
public Iterable<Task> getTasks() {
return taskRepository.findAll();
}
@PostMapping
public Task createTask(@RequestBody Task task) {
return taskRepository.save(task);
}
@GetMapping("/{id}")
public Task getTask(@PathVariable Long id) {
return taskRepository.findById(id).orElse(null);
}
@DeleteMapping("/{id}")
public void deleteTask(@PathVariable Long id) {
taskRepository.deleteById(id);
}
}
Веб-интерфейс
Создадим контроллер для отображения данных на веб-страницах с использованием Thymeleaf:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class WebController {
@Autowired
private UserRepository userRepository;
@Autowired
private TaskRepository taskRepository;
@GetMapping("/")
public String index(Model model) {
model.addAttribute("users", userRepository.findAll());
model.addAttribute("tasks", taskRepository.findAll());
return "index";
}
}
Результат выполнения
Запустите приложение и откройте в браузере http://localhost:8080
Вы увидите список пользователей и задач на главной странице.
Упражнения
Упражнение 1: Добавление возможности редактирования задач
Добавьте функциональность для редактирования существующих задач. Создайте эндпоинт и соответствующую веб-страницу для редактирования задачи.
Решение:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/tasks")
public class TaskController {
@Autowired
private TaskRepository taskRepository;
// Другие методы
@PutMapping("/{id}")
public Task updateTask(@PathVariable Long id, @RequestBody Task taskDetails) {
Task task = taskRepository.findById(id).orElse(null);
if (task != null) {
task.setDescription(taskDetails.getDescription());
task.setCompleted(taskDetails.isCompleted());
return taskRepository.save(task);
}
return null;
}
}
Объяснение: В этом решении добавляется метод updateTask
, который позволяет обновлять существующие задачи по их идентификатору. Добавьте соответствующую форму на веб-страницу для редактирования задач.
Упражнение 2: Фильтрация задач по статусу
Добавьте возможность фильтрации задач по статусу (выполненные/невыполненные). Создайте эндпоинт и соответствующую веб-страницу для отображения отфильтрованных задач.
Решение:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@RestController
@RequestMapping("/api/tasks")
public class TaskController {
@Autowired
private TaskRepository taskRepository;
// Другие методы
@GetMapping("/filter")
public Iterable<Task> getTasksByStatus(@RequestParam boolean completed) {
return taskRepository.findByCompleted(completed);
}
}
public interface TaskRepository extends CrudRepository<Task, Long> {
Iterable<Task> findByCompleted(boolean completed);
}
Объяснение: В этом решении добавляется метод getTasksByStatus
, который позволяет фильтровать задачи по статусу выполнения. Также обновляется интерфейс TaskRepository
для поддержки нового метода поиска.