Заменить значения в базе данных на данные, полученные из post-запроса Spring

Есть Controller с get и post запросами:

@GetMapping("/edit-user/{idUser}/{month}")
    public String editUser(@PathVariable("idUser") Long idUser, @PathVariable("month") int month,
                           Model model) {

        List<UserCalendar> users = calendarService.findUsersById(idUser);
        List<Event> events = calendarService.getEvents(users, month);
        List<Integer> days = calendarService.getDays(users, month);

        model.addAttribute("days", days);
        model.addAttribute("userEvents", events);
        model.addAttribute("allEvents", eventService.findAll());

        return "edit-user";
    }

@PostMapping("/edit-user")
    public String saveEvent(List<Event> allEvents) {

        eventService.saveAll(allEvents);

        return "redirect:/";
    }

Есть форма в thymeleaf

<form action="#" th:action="@{/edit-user}" th:object="${userEvents}" method="post">
   <td th:each="uc : ${userEvents}">
     <select id="allEvents" name="allEvents">
        <option th:each="allEvents : ${allEvents}"
                         th:value="${allEvents.idevent}"
                         th:text="${allEvents.event}"
                         th:selected="${allEvents.idevent} == ${uc.idevent}"></option>
     </select>
    </td>
    <input type="submit" value="Update User">
</form>

В браузере тело запроса выглядит следующим образом

введите сюда описание изображения

Вопрос в следующем: как вытащить эти значения из тела запроса?


Ответы (2 шт):

Автор решения: lampa

Я думаю нужно воспользоваться ModelAttribute для конвертации параметра в сущность Event:

@RestController
public class TestController {
    @ModelAttribute
    private List<Event> convert(String[] allEvents) {
        return Arrays.stream(allEvents).map(Event::new).collect(Collectors.toList());
    }

    @PostMapping("/edit-user")
    public String saveEvent(@RequestParam("allEvents") List<Event> allEvents) {
        allEvents.forEach(System.out::println);
        return "redirect:/";
    }
}
→ Ссылка
Автор решения: skipperoker

Решил вопрос с помощью создания EventFormDTO класса, а также переосмыслил работу form в Spring и thymeleaf (в моем вопросе не тот th:object взят + в @PostMapping параметр @ModelAttribute ("eventForm") EventForm eventForm.

Контроллер теперь выглядит так:

@GetMapping("/edit-user/{idUser}/{month}")
public String editUser(@PathVariable("idUser") Long idUser, @PathVariable("month") int month,
                       Model model) {

    List<UserCalendar> users = calendarService.findUsersById(idUser);
    List<Event> events = calendarService.getEvents(users, month);

    EventForm eventForm = new EventForm();
    eventForm.setEvents(events);

    model.addAttribute("eventForm", eventForm);
    model.addAttribute("allEvents", eventService.findAll());

    return "edit-user";
}

@PostMapping("/edit-user")
public String saveEvent(@ModelAttribute("eventForm") EventForm eventForm) {

    System.out.println(eventForm.getEvents());

    return "redirect:/";
}

Шаблон вот так:

<form action="#" th:action="@{/edit-user}" th:object="${eventForm}" method="post">
 <tr>
  <td th:each="uc : *{events}">
   <select id="events" name="events">
    <option th:each="allEvents : ${allEvents}"
            th:value="${allEvents.idevent}"
            th:text="${allEvents.event}"
            th:selected="${allEvents.idevent} == ${uc.idevent}">
    </option>
   </select>
  </td>
</tr>
  <input type="submit" value="Update User">
</form>

Класс EventFormDTO

@Data
@Setter
@Getter
public class EventFormDTO {
    private List<Event> events;
}

Осталось доработать saveEvent(), чтобы метод сохранял данные в бд.

→ Ссылка