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

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

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

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

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Thymeleaf

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

Spring Boot

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

Q&A

解決済

1回答

7984閲覧

SpringのWebアプリでの入力エラー時の画面遷移について

MoonlightEdgeGo

総合スコア27

Java

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

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Thymeleaf

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

Spring Boot

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

0グッド

1クリップ

投稿2018/03/14 02:45

編集2018/03/14 02:59

SpringBootを持ちいてWebアプリを作成しております。

その中でValidationエラー時の画面遷移の実装について迷ってしまいましたので質問いたします。

↓こうしてしまうとシンプルですが、入力エラーで戻った時にURLが変わってしまいます。

Java

1@Controller 2@RequestMapping("sample") 3class SampleController{ 4 5 // こいつはセッションスコープの@Component 6 @Autowired 7 private SampleDate sampleData; 8 9 @Autowired 10 private SampleService service; 11 12 @GetMapping("input") 13 public ModelAndView input(){ 14 return new ModelAndView("input"); 15 } 16 17 @PostMapping("confirm") 18 public ModelAndView confirm(@Validated SampleForm sampleForm, BindingResult bindingResult){ 19 if(bindingResult.hasErrors()){ 20 return new ModelAndView("input"); 21 } 22 sampleData.setSampleForm(sampleForm); 23 return new ModelAndView("confirm"); 24 } 25 26 @PostMapping("complete") 27 public ModelAndView complete(){ 28 servide.exec(sampleData); 29 return new ModelAndView("complete"); 30 } 31}

なのでリダイレクトで戻してやる必要があると思い、しかもエラーの内容は画面に表示してやりたいので、
↓のようにRedirectAttributeを用いてやってみました。
試行錯誤の結果、「BindingResult.MODEL_KEY_PREFIX + モデル名」で渡して、RequestContextUtilsを使うとうまくいったのですが、なんか複雑になってしまいました。

Java

1@Controller 2@RequestMapping("sample") 3class SampleController{ 4 5 // こいつはセッションスコープの@Component 6 @Autowired 7 private SampleDate sampleData; 8 9 @Autowired 10 private SampleService service; 11 12 @GetMapping("input") 13 public ModelAndView input(HttpServletRequest req){ 14 SampleForm form = sampleData.getSampleForm() 15 if(form == null){ 16 form = new SampleForm(); 17 } 18 ModelAndView mav = new ModelAndView("input"); 19 mav.addObject("sampleForm", form); 20 setErrorToModel(req, mav); 21 return mav; 22 } 23 24 @PostMapping("confirm") 25 public ModelAndView confirm(@Validated SampleForm sampleForm, BindingResult bindingResult, RedirectAttribute redirectAttribute){ 26 sampleData.setSampleForm(sampleForm); 27 if(bindingResult.hasErrors()){ 28 ModelAndView mav = new ModelAndView("redirect:./input"); 29 redirectAttribute.addFlashAttributes(BindingResult.MODEL_KEY_PREFIX + "sampleForm", bindingResult); 30 return mav; 31 } 32 return new ModelAndView("confirm"); 33 } 34 35 @PostMapping("complete") 36 public ModelAndView complete(){ 37 service.exec(sampleData); 38 return new ModelAndView("complete"); 39 } 40 41 private void setErrorToModel(HttpServletRequest req, ModelAndView mav) { 42 Map<String, ? > inputFlashMap = RequestContextUtils.getInputFlashMap(req); 43 if (inputFlashMap != null) { 44 inputFlashMap.forEach((k, v) -> mav.addObject(k, v)); 45 } 46 } 47}

URLを変えずにシンプルに実装する方法はないのでしょうか?
こうゆうケースのベストプラクティスが知りたいです。
よろしくお願いします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/03/14 10:03

先週解決済みを見た気がする
退会済みユーザー

退会済みユーザー

2018/03/14 11:12 編集

リターンをセットにかえるだけ -> return new ModelAndView(/* ここ */"complete");
MoonlightEdgeGo

2018/03/14 12:14

うぅ~すみません理解できていません。。。"redirect:/hoge""forward:/fuga"みたいな書き方が他にも存在するということでしょうか?
guest

回答1

0

ベストアンサー

一番簡単なのは、同じURLに対しHTTPメソッドで切り替える方法です。

実装されている内容を見るに、確認用(confirm)と完了(complete)も用意したいのだと思いますが、これは一緒のパスでよく、confirmでvalidationを通過したのを示す値(一時トークンのようなもの)もレスポンスし、完了時にはこのトークンが発行されたものと同じであるのを検証できて登録処理をするのが良いでしょう。

現在の実装だと、confirmのURLを通さずに直接completeへPOSTすると登録処理に行ってしまいますね。簡略化した内容で書くと、以下のようになるでしょうか。

java

1@GetMapping("") 2public ModelAndView input(HttpServletRequest req){ 3 4} 5 6@PostMapping("") 7public ModelAndView register(@Validated SampleForm sampleForm......){ 8 // Validationが通ったあと、一時トークンがなければ発行してcomfirmへ 9 10 // 一時トークンが正しい値であれば 登録処理をしてcompleteへ 11}

動作確認をする場合は、一時トークンの値は固定にしておいて、動かして見ると良いでしょう。その後にトークンの値をランダムにするとかなどで。

投稿2018/03/15 16:12

A-pZ

総合スコア12011

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問