久々にSpringBootを使って、画面の開発を行っている。
Tomcat等のAPサーバに縛られない開発はとても快適だ。
直近がRuby On Railsでの開発だったのもあり、Java屋の自分はホームゲームで戦えている気分。
そんな中、画面遷移時に画面遷移先の初期表示メソッドを呼び出せず、ThymeleafのWhitelabelエラーとなって、若干ハマった。
結論としては、redirectやforwardしないといけなかった。
環境
Windows10 Pro
SpringBoot2.2.5
Thymeleaf(spring-boot-starter-thymeleafをバージョン指定なしでmavenで指定)
発生した際のソースコード
AAAController.javaのsendメソッドからBBBController.javaのinitメソッドを呼び出し、BBB画面の呼び出し。
AAAController.java
@Controller @RequestMapping("/") public class AAAController { /** * AAA画面 初期表示 * * @param model 画面に返却するデータモデル * @return 画面のパス */ @RequestMapping(method = RequestMethod.GET) public String init(Model model) { return "aaa"; } /** * AAA画面 送信時 */ @PostMapping("/send") public String send(@ModelAttribute @Validated AAAForm aaaForm) { // 処理 // BBB画面へ遷移 return "bbb"; } }
BBBController.java
@Controller @RequestMapping("/bbb") public class BBBController { /** * BBB画面 初期表示 * * @param model 画面に返却するデータモデル * @return 画面のパス */ @RequestMapping(method = RequestMethod.GET) public String init(Model model) { // 処理 return "bbb"; } }
こんな感じの際に、 BBBController.javaのinit処理が走らず、画面に必要なModelの情報も設定されないため、Whitelabel画面が出てしまうという結果。
この
// BBB画面へ遷移
return "bbb";
という部分が、NGで、これだとHTMLの表示だけとなってしまう。
つまり、必要なモデルはAAAControllerのsendメソッド内で準備しないといけない状態となっている。これは求めている状態ではない。
そこで、下記のように修正した。
AAAController.java
@Controller
@RequestMapping("/")
public class AAAController {
/**
* AAA画面 初期表示
*
* @param model 画面に返却するデータモデル
* @return 画面のパス
*/
@RequestMapping(method = RequestMethod.GET)
public String init(Model model) {
return "aaa";
}
/**
* AAA画面 送信時
*/
@PostMapping("/send")
public String send(@ModelAttribute @Validated AAAForm aaaForm) {
// 処理
// BBB画面へ遷移
return "redirect:/bbb";
}
}
このようにリダイレクトさせることにした。
リダイレクトをすると、クライアントへリダイレクト先のURLを返却するので、クライアントは再度リダイレクト先のURLを実行することとなる。この動きは想定通り。
ちなみに、 "forward:/bbb"と書くと、該当するURLのコントローラーに処理を引き渡すことができる。クライアントからのリクエストは継続されるので、/aaa/sendのURLのまま、BBB画面が表示されることとなる。
HTMLの表示は初期表示では使いやすいが、画面遷移の際に行う処理ではないということでした。この辺、Railsだと意識せずにできたような記憶がある…