質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

4058閲覧

hiddenを使ってコントローラー側にエンティティを渡そうとしているが、上手く出来ない

shunji2740

総合スコア4

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Thymeleaf

Thymeleaf(タイムリーフ)とは、Java用のテンプレートエンジンで、特定のフレームワークに依存せず使用することが可能です。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2021/01/06 06:23

編集2021/01/06 06:56

実現したいこと

現在「Spring徹底入門」という書籍を参考に会議室予約システムを作っています。
書籍のチュートリアルに、ユーザー登録機能と確認画面を追加しようとしています。

発生している問題

今発生している問題は、confirmReservation.htmlの完了ボタンを押すとWhitelabel Error Pageが出てきます。

confirmReservation.htmlからreservationエンティティをhiddenを使ってReservationsController側のconfirmedメソッドに渡し予約処理をしようとしていますが、confirmedメソッドが呼び出されません。ブラウザにはWhitelabel Error Pageが表示されてしまいます。reservationエンティティを上手くコントローラ側が受け取れていないのだと思います。
コンソール画面にはエラーなどが出ていない為、何が原因なのか分かりづらいです。

###エラー内容

Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Wed Jan 06 14:26:11 JST 2021 There was an unexpected error (type=Bad Request, status=400).

該当のソースコード

confirmeReservation

1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org" 3 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-spring-security5"> 4<head> 5<meta charset="UTF-8"> 6<title></title> 7 <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous"> 8 <link href="https://getbootstrap.com/docs/4.0/examples/signin/signin.css" rel="stylesheet" crossorigin="anonymous"/> 9 10</head> 11<body> 12 <div> 13 <h2>ご予約内容の確認</h2> 14 15 <table> 16 <tr> 17 <th>時間帯</th> 18 <th>予約者</th> 19 <th>操作</th> 20 </tr> 21 22 <tr> 23 <td> 24 <span th:text="${reservation.startTime}"></span> 25 <span th:text="${reservation.endTime}"></span> 26 </td> 27 <td> 28 <span th:text="${reservation.user.lastName}"></span> 29 <span th:text="${reservation.user.firstName}"></span> 30 </td> 31 </tr> 32 </table> 33 </div> 34 35 <!-- 登録完了処理 --> 36 <form th:action="@{'/reservations/' + ${date} + '/' + ${roomId}}" method="post" > 37 <input type="hidden" name="reservation" th:value="${reservation}" /> 38 <input type="submit" name="confirmed" value="完了" /> 39 </form> 40</body> 41</html>

ReservationsController

1package mrs.app.reservation; 2 3import java.time.LocalDate; 4import java.time.LocalTime; 5import java.util.List; 6import java.util.stream.Collectors; 7import java.util.stream.Stream; 8 9import javax.servlet.http.HttpSession; 10 11import org.springframework.beans.factory.annotation.Autowired; 12import org.springframework.format.annotation.DateTimeFormat; 13import org.springframework.security.access.AccessDeniedException; 14import org.springframework.security.core.annotation.AuthenticationPrincipal; 15import org.springframework.stereotype.Controller; 16import org.springframework.ui.Model; 17import org.springframework.validation.BindingResult; 18import org.springframework.validation.annotation.Validated; 19import org.springframework.web.bind.annotation.ModelAttribute; 20import org.springframework.web.bind.annotation.PathVariable; 21import org.springframework.web.bind.annotation.RequestMapping; 22import org.springframework.web.bind.annotation.RequestMethod; 23import org.springframework.web.bind.annotation.RequestParam; 24import org.springframework.web.servlet.mvc.support.RedirectAttributes; 25 26import mrs.domain.model.ReservableRoom; 27import mrs.domain.model.ReservableRoomId; 28import mrs.domain.model.Reservation; 29import mrs.domain.model.User; 30import mrs.domain.service.reservation.AlreadyReservedException; 31import mrs.domain.service.reservation.ReservationService; 32import mrs.domain.service.reservation.UnavailableReservationException; 33import mrs.domain.service.room.RoomService; 34import mrs.domain.service.user.ReservationUserDetails; 35 36@Controller 37@RequestMapping("reservations/{date}/{roomId}") 38public class ReservationsController { 39 40 @Autowired 41 RoomService roomService; 42 43 @Autowired 44 ReservationService reservationService; 45 46 @Autowired 47 HttpSession session; 48 49 //予約確認・予約一覧画面 50 //予約可能かの確認作業はreserve()にて 51 @RequestMapping(method = RequestMethod.GET) 52 String reserveForm(@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) @PathVariable("date") LocalDate date, 53 @PathVariable("roomId") Integer roomId, Model model, 54 @AuthenticationPrincipal ReservationUserDetails userDetailss) { 55 56 // authorities に想定した権限(ROLE_ADMIN など)が含まれるか? 57 //Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities(); 58 59 //指定日かつ指定会議室のreservableRoomIdを生成 60 ReservableRoomId reservableRoomId = new ReservableRoomId(roomId, date); 61 62 //指定日かつ指定会議室の予約リストを取得 63 List<Reservation> reservations = reservationService.findReservations(reservableRoomId); 64 65 //LocalDateオブジェクトを作成してリストに格納する 66 List<LocalTime> timeList = Stream.iterate(LocalTime.of(0, 0), t -> t.plusMinutes(30)) 67 .limit(24 * 2) 68 .collect(Collectors.toList()); 69 70 model.addAttribute("room", roomService.findMeetingRomm(roomId)); 71 model.addAttribute("reservations", reservations); 72 model.addAttribute("timeList", timeList); 73 74 // Flash Scopeから値の取り出し 75 Boolean booleanResult = (Boolean) model.getAttribute("booleanResult"); 76 model.addAttribute("booleanResult", booleanResult); 77 78 return "reservation/reserveForm"; 79 80 } 81 82 //予約処理・予約可能かの処理 83 @RequestMapping(method = RequestMethod.POST) 84 String reserve(@Validated ReservationForm form, BindingResult bindingResult, 85 @AuthenticationPrincipal ReservationUserDetails userDetails, 86 @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) @PathVariable("date") LocalDate date, 87 @PathVariable("roomId") Integer roomId, Model model) { 88 89 if (bindingResult.hasErrors()) { 90 return reserveForm(date, roomId, model, userDetails); 91 } 92 93 Reservation reservation = new Reservation(); 94 reservation.setStartTime(form.getStartTime()); 95 reservation.setEndTime(form.getEndTime()); 96 ReservableRoom reservableRoom = new ReservableRoom(new ReservableRoomId(roomId, date)); 97 reservation.setReservableRoom(reservableRoom); 98 reservation.setUser(userDetails.getUser()); 99 100 try { 101 //ここではじめてreservable_roomに登録されているか、重複していないかをチェックする 102 reservationService.checkReservation(reservation); 103 104 } catch (UnavailableReservationException | AlreadyReservedException e) { 105 model.addAttribute("error", e.getMessage()); 106 return reserveForm(date, roomId, model, userDetails); 107 } 108 109 //session.setAttribute("reservation", reservation); 110 model.addAttribute("reservation", reservation); 111 112 return "reservation/confirmReservation"; 113 } 114 115 116 117 ★ここに上手くreservationエンティティが渡せない、そもそもメソッドの中に入らない★ 118 //予約完了 119 @RequestMapping(method = RequestMethod.POST, params = "confirmed") 120 String confirmed(RedirectAttributes redirectAttributes, @ModelAttribute("reservation") Reservation reservation, Model model) { 121 122 //予約を登録する 123 reservationService.reserve(reservation); 124 125 redirectAttributes.addFlashAttribute("booleanResult", true); 126 127 return "redirect:/reservations/{date}/{roomId}"; 128 } 129 130 131 132 133 //予約削除 134 @RequestMapping(method = RequestMethod.POST, params = "cancel") 135 String cancel(@RequestParam("reservationId") Integer reservationId, 136 @AuthenticationPrincipal ReservationUserDetails userDetails, 137 @PathVariable("roomId") Integer roomId, 138 @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) @PathVariable("date") LocalDate date, Model model) { 139 140 //ユーザー取得 141 User user = userDetails.getUser(); 142 143 try { 144 reservationService.cancel(reservationId, user); 145 146 } catch (AccessDeniedException e) { //ハンドリングする例外はAccessDeniedException 147 model.addAttribute("error", e.getMessage()); 148 return reserveForm(date, roomId, model, userDetails); 149 } 150 151 return "redirect:/reservations/{date}/{roomId}"; 152 } 153 154 //予約時間のデフォルトForm 155 @ModelAttribute 156 ReservationForm setUpForm() { 157 ReservationForm form = new ReservationForm(); 158 //デフォルト値 159 form.setStartTime(LocalTime.of(9, 0)); 160 form.setEndTime(LocalTime.of(10, 0)); 161 162 return form; 163 } 164 165} 166

試したこと

@RequestParamなども試してみましたが、上手く渡せませんでした。
試しにreservationエンティティをsessionに保持させた場合は、上手くできました。
色々と調べましたが、解決に至らずここで質問をさせて頂きます。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/01/06 06:28

どの時点で出ているエラーでしょうか
shunji2740

2021/01/06 06:38

ご指摘ありがとうございます。 エラーが発生しているのは、ReservationsController側のconfirmedメソッドのところです。 デバックで確認したところ、confirmedメソッド自体が呼び出されていませんでした。 もし、まだ追記・修正依頼がありましたらよろしくお願いします。
m.ts10806

2021/01/06 06:40

いえあの、「操作」のことです。 どういう操作をしたときに起きている現象なのか。 例:アクセスしてすぐ。入力して送信ボタン押したら などなど
shunji2740

2021/01/06 06:53

予約確認ページのconfirmReservation.htmlまでは問題はありません。 けれど、confirmReservation.htmlの完了ボタンを押すとWhitelabel Error Pageが出てきます。
m.ts10806

2021/01/06 07:01

ViewにdateやroomIdを渡す記述が見受けられないのですが、 PathVariableで受け取った情報って何もしなくてもViewに渡せましたっけ? ただ確かにエラーが出ないのは不自然ではありますが。
shunji2740

2021/01/06 07:12

すいません、dateやroomIdを渡しているのは予約確認ページの前のreserveForm.htmlの所です。 該当のソースコードにreserveForm.htmlを追記しようとしましたが、10000文字以上なので追記出来ませんでした。
m.ts10806

2021/01/06 07:14

あぁ。。理解しました。
shunji2740

2021/01/06 07:15

お手数お掛けしました、すいません。。
guest

回答1

0

ベストアンサー

<input type="hidden" name="reservation" th:value="${reservation}" />

大前提として、HTMLに出力できるのは文字列だけです。
JSON形式に変換しているなら「文字列」として認識できるのでともかく
見た感じ${reservation}はあくまでJavaのReservationオブジェクトを保持しています。
「確認画面から登録画面に渡したい」のでしたら、hiddenで全項目1つ1つ入れて送信するか
試されたようにセッションを使うことになるかと思います。

投稿2021/01/06 07:16

m.ts10806

総合スコア80861

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shunji2740

2021/01/06 07:22

了解しました、hiddenだと全項目を1づつ入れて送信しないといけないのですね... 仰ってる通り、sesssionを使おうと思います。ご指摘ありがとうございました。
m.ts10806

2021/01/06 07:25

HTMLを出力している場合、ブラウザから「ソースを表示」もしくはブラウザのデベロッパツールを使い「想定の情報が出力されているか」「何がhiddenに入っているか」を確認する癖をつけると良いかと思います。 たぶん今回は何も出力されてないか、オブジェクト文字列(この表現が正しいか分からない)が表示されているものと思います。
shunji2740

2021/01/07 00:31

ブラウザのデベロッパツールを使用し、hiddenに入っている値を確認したところオブジェクト文字列が入っていました。今後はHTMLを出力する場合は、デベロッパツールを使用して値の確認を行うようにいたします。ご指摘ありがとうございました。
m.ts10806

2021/01/07 00:53

一つ一つhiddenというのを書いたものの、やはり悪手ですね。 デベロッパツールから値を改ざんしてしまえるので、再度バリデーションが必要になります。 やはりセッションを選択すべき場面です。
shunji2740

2021/01/07 04:51

んー、なるほど了解いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問