【Spring Boot】ModelクラスとModel And Viewクラス

Spring Bootのプロジェクトでは
コントローラーからビュー側へデータの値を渡す処理を行う場合、
Spring FrameworkのModelクラスもしくはModel And Viewクラスを利用して実現させますが
両者のそれぞれの特徴と利用の仕方の違いについてまとめます。

なお、本記事で題材にしているプロジェクトのソースコードは
WEB+DB PRESS Vol.106の特集記事を参考にしています。

Model And Viewクラスを利用する場合

//同Controller クラスフィールド
private static final String TASKS = "tasks";

@Autowired 
TodoService todoService;
@GetMapping("/tasks")
public ModelAndView readAllTasks(ModelAndView modelAndView) {
	    TaskForm form = createInitialForm(); //オブジェクト生成の初期メソッド呼び出し

	    modelAndView.addObject("form", form);
	
        List<Task> tasks = todoService.findAllTasks(); //データベースからデータを取得
	
        modelAndView.addObject(TASKS, tasks);
	
        modelAndView.setViewName(TASKS);
	
        return modelAndView;
}

リクエストを受けつけるメソッドにModelAndView型の引数を指定する。
(modelAndViewとしている)

戻り値の型もModelAndViewクラスで定義する必要がある。

(5行目と9行目)
addObject()メソッドではView側へ渡すオブジェクトのデータを
第一引数にテンプレートから参照する変数名、
第二引数にオブジェクト名として格納している。

(11行目)
setViewName()メソッドで、遷移先を指定している。

サンプルではクラスフィールドにあらかじめ定義した定数TASKを引数に渡している。

データ情報、View情報(テンプレート名)を持ったModelAndViewオブジェクトをreturnすることで
“tasks.html”へ遷移させる。

Modelクラスを利用する場合

※上記のModelAndView解説時と同じクラスフィールドを利用する

@GetMapping("/tasks")
public String readAllTasks(Model model) {
	TaskForm form = createInitialForm();
	model.addAttribute("form", form);
	List<Task> tasks = todoService.findAllTasks();
	model.addAttribute(TASKS, tasks); 
	return TASKS;
}

ModelAndViewクラスと同じように、
リクエストを受け取るメソッドにModelクラス型の引数を取る。
(modelとしている)

遷移先のテンプレート名を文字列としてreturnするので、
メソッドの戻り値の型はString型にする必要がある。

(4行目、6行目)
addAttribute()メソッドでView側へ渡すオブジェクトのデータを
第一引数にテンプレートから参照する変数名、
第二引数にオブジェクト名として格納している。

(7行目)
returnで遷移先のテンプレート名前を文字列として指定する。
こちらもあらかじめ定義した定数TASKを指定して”tasks.html”へ遷移させている。


両者の違いをまとめる

前者のModelAndViewの場合、
オブジェクトにデータの値とビューの情報をまとめて格納するのに対して、
後者のModelはオブジェクトにデータの値だけを格納する仕組みになっています。
(Viewの情報はメソッドの戻り値として指定する)

どちらもリクエストハンドリングのメソッドの引数として利用することは共通しており、
必要なパッケージがクラスにインポートされます。

addObject、addAttributeで格納したデータの変数名はいずれも
View側のThymeleafテンプレートからは${変数名}という形で利用することが出来ます。

ModelAndViewクラスとModelクラスでどちらも同様の処理を実現出来ますが
クラスごとに異なる書き方が混在しないようプロジェクト内で統一させるのが良いかと思います。

Follow me!