回答編集履歴

2

修正

2020/02/07 07:08

投稿

rubytomato
rubytomato

スコア1752

test CHANGED
@@ -251,3 +251,193 @@
251
251
  <input type="text" class="form-control" placeholder="id" id="id" name="id" th:value="${info.id}">
252
252
 
253
253
  ```
254
+
255
+
256
+
257
+ ### 追記(2020/02/07)
258
+
259
+
260
+
261
+ > この時infoは⑤のところで引数として受け取っているので⑥でhello.htmlを呼び出したときに過去の入力値がth:field="*{id}"のようにして表示できるのはわかるのですが
262
+
263
+
264
+
265
+ 説明に不正確な点がありましたのでお詫びと訂正をさせて頂きます。
266
+
267
+ 下記のコードを『リダイレクト元からの情報を受け取るためにパラメータを定義』と説明しましたが、正確にはリダイレクト元でセットされたinfoはモデルの属性に存在しているので受け取るためだけであればパラメータの定義は不要です。
268
+
269
+
270
+
271
+ ```java
272
+
273
+ @GetMapping("/hello")
274
+
275
+ //★(2) リダイレクト元からの情報を受け取るためにパラメータを定義
276
+
277
+ public String hello(@ModelAttribute("info") LoginInfoBean info) {
278
+
279
+ return "hello";
280
+
281
+ }
282
+
283
+ ```
284
+
285
+
286
+
287
+ ただし、下記の実装だとリダイレクトしてきた時に、新しいインスタンスでモデルの属性のinfoを更新してしまいます。
288
+
289
+
290
+
291
+ ```java
292
+
293
+ @GetMapping("/hello")
294
+
295
+ public String hello(Model model) {
296
+
297
+ model.addAttribute("info", new LoginInfoBean());
298
+
299
+ return "hello";
300
+
301
+ }
302
+
303
+ ```
304
+
305
+
306
+
307
+ なので、直接アクセスとリダイレクトされてくることを意識したコードは、下記のようになります。
308
+
309
+
310
+
311
+ ```java
312
+
313
+ @GetMapping("/hello")
314
+
315
+ public String hello(Model model) {
316
+
317
+ // モデルの属性にinfoが存在しない場合は、インスタンスを生成してモデルの属性にセット。
318
+
319
+ // これは直接helloにアクセスするユーザーを想定した処理。
320
+
321
+ if (!model.containsAttribute("info")) {
322
+
323
+ model.addAttribute("info", new LoginInfoBean());
324
+
325
+ } else {
326
+
327
+ // モデルの属性にinfoが存在するということは、リダイレクト元でセットされている。
328
+
329
+ System.out.println(model.getAttribute("info"));
330
+
331
+ // 同様に、リダイレクト元でmessageがセットされていれば、モデルの属性にmessageも存在している。
332
+
333
+ System.out.println(model.getAttribute("message"));
334
+
335
+ }
336
+
337
+ return "hello";
338
+
339
+ }
340
+
341
+ ```
342
+
343
+
344
+
345
+ このコードを簡略化したのが、回答で提示した下記のコードになります。
346
+
347
+ 直接アクセスしたユーザーは生成された(空の)インスタンス、リダイレクトしてきたユーザーは元の入力情報を持つインスタンスがモデルの属性にセットされています。
348
+
349
+ ※helloメソッド内でinfoについて何か処理を行うということがなければ、このコードではなく上記のコードが適切かと思います。
350
+
351
+
352
+
353
+ ```java
354
+
355
+ @GetMapping("/hello")
356
+
357
+ public String hello(@ModelAttribute("info") LoginInfoBean info) {
358
+
359
+ return "hello";
360
+
361
+ }
362
+
363
+ ```
364
+
365
+
366
+
367
+ > redirectAttributes.addFlashAttribute("message", "認証に失敗しました");については何も指定しなくても表示できるのでしょうか?
368
+
369
+
370
+
371
+ messageについても、infoと同様にモデルの属性に存在していれば、テンプレート(html)で表示できます。
372
+
373
+
374
+
375
+ 最後にflashスコープについて補足致します。
376
+
377
+ bunkiメソッドでリダイレクト先にinfoやmessageを渡すために`addFlashAttribute`というメソッドを使っていますが、これはflashスコープというスコープに登録しています。
378
+
379
+ flashスコープとはリダイレクト先に情報を渡すためのスコープで一度だけ使えます。
380
+
381
+ 一度だけというのは、一度表示するとその情報は消えるという意味で、例えば認証成功後のokページでF5キーを押してページを更新するとメッセージは表示されません。
382
+
383
+
384
+
385
+ アクセスフローと併せてご覧ください。
386
+
387
+
388
+
389
+ ```
390
+
391
+ [client]
392
+
393
+ +--------+
394
+
395
+ | | redirect:hello
396
+
397
+ | | (flash = info,message)
398
+
399
+ | ---|-----------------------------------------------------------------------
400
+
401
+ | | | |
402
+
403
+ | | | |
404
+
405
+ | | | +---------+ +--------+ |
406
+
407
+ | ---|--> /hello -(2)-> | | | | - failure --
408
+
409
+ | | | hello | [post] | /bunki |
410
+
411
+ | ------|--> /hello -(1)-> | .html | (request = info) | | - success --
412
+
413
+ | | (request = info) +---------+ +--------+ |
414
+
415
+ | | |
416
+
417
+ | ---|-----------------------------------------------------------------------
418
+
419
+ | | | redirect:ok
420
+
421
+ | | | (flash = message)
422
+
423
+ | | | +----------+
424
+
425
+ | | | | |
426
+
427
+ | ---|-----------------------------------------------------> /ok -(3)-> | ok.html |
428
+
429
+ | | | |
430
+
431
+ | | +----------+
432
+
433
+ +--------+
434
+
435
+ ```
436
+
437
+
438
+
439
+ * /hello -(1)-> は、直接アクセスするユーザーの流れ、requestスコープに空のinfoを持つ
440
+
441
+ * /hello -(2)-> は、認証失敗でリダイレクトしたユーザーの流れ、info、messageをflashスコープに持つ
442
+
443
+ * /ok -(3)-> は、認証成功でリダイレクトしたユーザーの流れ、messsageをflashスコープに持つ

1

追記

2020/02/07 07:08

投稿

rubytomato
rubytomato

スコア1752

test CHANGED
@@ -70,6 +70,8 @@
70
70
 
71
71
  @GetMapping("/hello")
72
72
 
73
+ //★(2) リダイレクト元からの情報を受け取るためにパラメータを定義
74
+
73
75
  public String hello(@ModelAttribute("info") LoginInfoBean info) {
74
76
 
75
77
  return "hello";
@@ -104,6 +106,8 @@
104
106
 
105
107
 
106
108
 
109
+ //★(1) 認証失敗時の情報をリダイレクト先へ渡す
110
+
107
111
  redirectAttributes.addFlashAttribute("info", info);
108
112
 
109
113
  redirectAttributes.addFlashAttribute("message", "認証に失敗しました");
@@ -130,12 +134,16 @@
130
134
 
131
135
  <div class="form-group">
132
136
 
137
+ <!--★(3) th:field="*{id}"でフォームにセット -->
138
+
133
139
  <input type="text" class="form-control" placeholder="id" th:field="*{id}">
134
140
 
135
141
  </div>
136
142
 
137
143
  <div class="form-group">
138
144
 
145
+ <!--★(4) th:field="*{pw}"でフォームにセット-->
146
+
139
147
  <input type="text" class="form-control" placeholder="pw" th:field="*{pw}">
140
148
 
141
149
  </div>
@@ -151,3 +159,95 @@
151
159
  </form>
152
160
 
153
161
  ```
162
+
163
+
164
+
165
+ ### 追記(2020/02/06)
166
+
167
+
168
+
169
+ > ただ一点気になるところがあって、補足で教えていただいたものは元の入力値が認証失敗時にidとpw欄にそれぞれ入力されたままになるということでしょうか?
170
+
171
+ 上記のとおりやってみたのですが、失敗時はidもpwもクリアされてしまうようで…
172
+
173
+
174
+
175
+ 上記のコメントを受けて、改修案にコメントを追加しました。
176
+
177
+ 認証失敗時にフォーム画面に元の入力値を表示させるには下記4カ所のコードが必要です。
178
+
179
+ ★(1)~★(2)はリダイレクト間で情報を持ちまわすためのコード、★(3)、★(4)はリダイレクト元から持ちまわされた情報をフォームフィールドにセットするためのコードです。
180
+
181
+
182
+
183
+ **bunkiメソッド**
184
+
185
+
186
+
187
+ ```
188
+
189
+ //★(1) 認証失敗時の情報をリダイレクト先へ渡す
190
+
191
+ redirectAttributes.addFlashAttribute("info", info);
192
+
193
+ ```
194
+
195
+
196
+
197
+ **helloメソッド**
198
+
199
+
200
+
201
+ ```
202
+
203
+ //★(2) リダイレクト元からの情報を受け取るためにパラメータを定義
204
+
205
+ public String hello(@ModelAttribute("info") LoginInfoBean info)
206
+
207
+ ```
208
+
209
+
210
+
211
+ **hello.html**
212
+
213
+
214
+
215
+ ※関係のない部分は省略しています。
216
+
217
+
218
+
219
+ ```
220
+
221
+ <form th:action="@{/bunki}" th:object="${info}" method="post">
222
+
223
+
224
+
225
+ <!--★(3) th:field="*{id}"でフォームにセット -->
226
+
227
+ <input type="text" class="form-control" placeholder="id" th:field="*{id}">
228
+
229
+
230
+
231
+ <!--★(4) th:field="*{pw}"でフォームにセット-->
232
+
233
+ <input type="text" class="form-control" placeholder="pw" th:field="*{pw}">
234
+
235
+
236
+
237
+ </forM
238
+
239
+ ```
240
+
241
+
242
+
243
+ なお、`th:field="*{id}"`という書き方は、`th:field="${info.id}"`と同じ意味です。
244
+
245
+ さらには、少し冗長化して書くと下記のようになります。
246
+
247
+
248
+
249
+ ```
250
+
251
+ <input type="text" class="form-control" placeholder="id" id="id" name="id" th:value="${info.id}">
252
+
253
+ ```