実現したいこと
セレクトの範囲を9:00~10:00までにしたい。
前提
spring bootで予約管理システムを作っています。
予約の時間を決める機能を実装中に以下のエラーメッセージが発生しました。
発生している問題・エラーメッセージ
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/reservation/reserveFrom.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/reservation/reserveFrom.html]")
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring6.processor.SpringSelectFieldTagProcessor' (template: "reservation/reserveFrom" - line 23, col 11)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring6.processor.SpringSelectFieldTagProcessor' (template: "reservation/reserveFrom" - line 23, col 11)
Caused by: org.springframework.beans.NotReadablePropertyException: Invalid property 'startTime' of bean class [com.example.demo.app.reservaition.ReservationForm]: Bean property 'startTime' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
該当のソースコード
ReservationForm.java
package com.example.demo.app.reservaition; import java.io.Serializable; import java.time.LocalTime; import org.springframework.format.annotation.DateTimeFormat; import jakarta.validation.constraints.NotNull; public class ReservationForm implements Serializable { @NotNull(message="必須です") @DateTimeFormat(pattern = "HH:mm") private LocalTime startTime; @NotNull(message="必須です") @DateTimeFormat(pattern = "HH:mm") private LocalTime endTime; public LocalTime getStartTime() { return startTime; } public void setStartTime(LocalTime startTime) { this.startTime = startTime; } public LocalTime getEndTime() { return endTime; } public void setEndTime(LocalTime endTime) { this.endTime = endTime; } }
ReservationsController.java
package com.example.demo.controller.java; import java.time.LocalDate; import java.time.LocalTime; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.example.demo.app.reservaition.ReservationForm; import com.example.demo.domain.model.ReservableRoom; import com.example.demo.domain.model.ReservableRoomId; import com.example.demo.domain.model.Reservation; import com.example.demo.domain.model.RoleName; import com.example.demo.domain.model.User; import com.example.demo.domain.service.reservation.AlreadyReservedException; import com.example.demo.domain.service.reservation.ReservationService; import com.example.demo.domain.service.reservation.UnavailableReservationException; import com.example.demo.domain.service.room.RoomService; @Controller @RequestMapping("reservations/{date}/{roomId}") public class ReservationsController { @Autowired RoomService roomService; @Autowired ReservationService reservationService; @ModelAttribute ReservationForm setUpForm(Model model) { ReservationForm form = new ReservationForm(); form.setStartTime(LocalTime.of(9, 0)); form.setEndTime(LocalTime.of(10, 0)); model.addAttribute("reservationForm", form); // モデルに追加する return form; } @RequestMapping(method = RequestMethod.GET) String reserveFrom(@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) @PathVariable("date")LocalDate date, @PathVariable("roomId")Integer roomId, Model model){ ReservableRoomId reservableRoomId = new ReservableRoomId(roomId, date); List<Reservation> reservations = reservationService.findReservations(reservableRoomId); List<LocalTime> timeList = Stream.iterate(LocalTime.of(0, 0),t -> t.plusMinutes(30)) .limit(24*2) .collect(Collectors.toList()); model.addAttribute("room",roomService.findMeetingRoom(roomId)); model.addAttribute("reservations", reservations); model.addAttribute("timeList", timeList); model.addAttribute("user", dummyUser()); return "reservation/reserveFrom"; } private User dummyUser() { User user = new User(); user.setUserid("taro-yamada"); user.setFirstName("太郎"); user.setLastName("山田"); user.setRoleName(RoleName.USER); return user; } }
reserveFrom.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title th:text="${#temporals.format(date, 'yyyy/M/d')} + 'の' + ${room.isPresent() ? room.get().roomName : '部屋なし'}">2024/1/1の函館</title> </head> <body> <div> <a th:href="@{'/rooms/' + ${date}}">会議室へ</a> </div> <form th:object="${reservationForm}" th:action="@{'/reservations/' + ${date} + '/' + ${roomId}}" method="post"> 会議室:<span th:text="${room.isPresent() ? room.get().roomName : '部屋なし'}"></span> <br/> 予約者名:<span th:text="${user.lastName + ' ' + user.firstName}">山田太郎</span> <br/> 日付:<span th:text="${#temporals.format(date, 'yyyy/M/d')}">2024/1/1</span> <br/> 時間帯: <select th:field="*{startTime}"> <option th:each="time : ${timeList}" th:text="${time}" th:value="${time.toString()}"></option> </select> <span th:if="${#fields.hasErrors('startTime')}" th:errors="*{startTime}" style="color:red">error!</span> <br/> - <select th:field="*{endTime}"> <option th:each="time : ${timeList}" th:text="${time}" th:value="${time.toString()}"></option> </select> <span th:if="${#fields.hasErrors('endTime')}" th:errors="*{endTime}" style="color:red">error!</span> <button type="submit">予約</button> </form> <table> <tr> <th>時間帯</th> <th>予約者</th> <th>操作</th> </tr> <tr th:each="reservation : ${reservations}"> <td> <span th:text="${reservation.startTime} + ' - ' + ${reservation.endTime}"></span> </td> <td> <span th:text="${reservation.user.lastName} + ' ' + ${reservation.user.firstName}"></span> </td> <td> <form th:action="@{'/reservations/' + ${date} + '/' + ${roomId}}" method="post" th:if="${user.userId == reservation.user.userId}"> <input type="hidden" name="reservationId" th:value="${reservation.reservationId}"> <input type="submit" name="cancel" value="取消"> </form> </td> </tr> </table> </body> </html>
試したこと
プロジェクトをリフレッシュした。
<select th:field="*{startTime}" name="startTime">を<select th:field="*{reservationForm.startTime}" name="startTime">にした。

0 コメント