Чтобы подобрать Spring, я играю с очень простыми страницами, чтобы понять аннотации и поведение Spring в целом.Если быть точным, я создал страницу для отображения списка Task
и другую страницу для добавления нового Task
.Я использовал @SessionAttibutes
, чтобы сохранить список задач в сеансе, вместо вызова службы для получения полного списка Task
каждый раз, когда я получаю доступ к странице списка задач.
Это мой TaskService
@Service
public class TaskService {
private List<Task> taskCache = new ArrayList<Task>();
public List<Task> retrieveTasks() {
System.out.println("GETTING TASK LIST FOR THE FIRST TIME");
return taskCache;
}
public Task addTask(String title, String desc, Date targetDate) {
Task newTask = new Task(title, desc, targetDate);
taskCache.add(newTask);
return newTask;
}
}
Это мой TaskController
@Controller
@SessionAttributes("taskList")
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/task-view")
public String showTaskList() {
return "task/view";
}
@GetMapping("/task-add")
public String showAddTaskForm(@ModelAttribute("task") Task newTask) {
return "task/add";
}
@PostMapping("/task-add")
public String addTask(ModelMap model, @ModelAttribute("task") Task newTask, @ModelAttribute("taskList") List<Task> taskList) {
System.out.println("ADDING NEW TASK: " + taskList.size());
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
System.out.println("DONE ADDING NEW TASK: " + taskList.size());
return "redirect:/task-view";
}
@ModelAttribute("taskList")
public List<Task> taskList() {
System.out.println("CALLING TASK SERVICE TO GET LIST OF TASKS");
return taskService.retrieveTasks();
}
}
Это мой view.jsp
<html>
<head>
<title>Task Page</title>
</head>
<body>
This is your task list:
${taskList}
<div>
<a href="task-add">Add a task</a>
</div>
</body>
</html>
Это мой add.jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>Task Page</title>
</head>
<body>
<form:form method="POST" action="/task-add" modelAttribute="task">
<div>
<form:label path="title">Title</form:label>
<form:input path="title" />
</div>
<div>
<form:label path="desc">Description</form:label>
<form:input path="desc" />
</div>
<div>
<input type="submit" value="Add">
</div>
</form:form>
</body>
</html>
С точки зрения атрибута сессий, он работает, как я ожидал.Функция TaskService.retrieveTasks()
вызывается только при первом доступе к view.jsp
.Впоследствии тот же список задач извлекается из сеанса.
Проблема заключается в том, что когда я пытаюсь добавить два новых Task
на страницу add.jsp
, я вижу следующие строки в консоли.
CALLING TASK SERVICE TO GET LIST OF TASKS
GETTING TASK LIST FOR THE FIRST TIME
ADDING NEW TASK: 0
DONE ADDING NEW TASK: 2
ADDING NEW TASK: 2
DONE ADDING NEW TASK: 4
Первые две строки были напечатаны, когда я в первый раз получил доступ к view.jsp
, что верно.Однако я понятия не имею, что происходит между ADDING NEW TASK
и DONE ADDING NEW TASK
линиями.Я был бы очень признателен, если бы кто-нибудь мог объяснить мне, почему строка ниже добавляет дубликат в моем списке Task
taskList.add(taskService.addTask(newTask.getTitle(), newTask.getDesc(), new Date()));
Я также попытался удалить часть taskList.add()
и только сделалсервисный звонок на taskService.addTask()
.В этом случае дубликатов нет, и мой taskList
обновляется одной новой записью.Однако я не понимаю, как taskService
мог косвенно изменить мой taskList
, когда в классе TaskService
нет инъекций.
Я что-то пропустил?