概要
Spring MVCで入力フォームを使用して画面とサーバー間で簡単なデータの受け渡しを行ったのでまとめた。
概要 Springを学びなおすにあたり、Spring MVCでHello Worldしたのでその方法についてまとめた。 今回はアノテーションベースのBean定義方法で実装した。 Spring MVCの特徴 Spr[…]
画面遷移
今回作成する画面の流れは以下となる。
Spring MVCのアーキテクチャ
Spring MVCを使用して画面とサーバー間でデータのやりとりを行う際に、内部では以下のような構造になっている。
Spring MVCでは画面とサーバー間でデータをやりとりする際に、以下のような流れで疎通する。
Modelオブジェクトは、画面とサーバー間でデータをやりとりするための箱のようなもの。
作成したModelをコントローラーに渡す。
コントローラーにて必要なデータ(EntityやFormなど)をModelに追加する。
フロントコントローラーはコントローラーから返却された画面名をもとに、viewインターフェイスを呼ぶ。
viewインターフェイスにて、Modelに格納されているデータをJSPからアクセスできる領域にエクスポートする。
JSPから上記領域を参照することで、サーバーから渡された値を画面にバインドすることができる。
ポイントはModelオブジェクトを使用して画面とサーバー間でやりとりを行うということ。
入力画面
入力フォームを表示する画面を作成する。
全体像
全体的な処理のイメージは以下となる。
「http://localhost:8080/test」がGETリクエストされると、TestControllerのshowInputメソッドにルーティングされる。
showInputメソッドではフォームを作成して、入力フォームを表示する画面名を返却する。
入力画面表示処理
入力画面を表示するための実装を行う。
pom.xml
フォームクラスのゲッターセッターをシンプルにするため、lombokライブラリを導入する。
pom.xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope> <!-- providedスコープが指定されたライブラリは、コンパイル時にのみ必要とされる。 -->
</dependency>
フォームクラス
画面入力値を受け取るため、フォームクラスを作成する。
TestForm.java
package com.example.app.form;
import java.io.Serializable;
import lombok.Data;
@Data
public class TestForm implements Serializable{
private String text;
}
コントローラー
URLとGETメソッドに紐づくメソッドを作成する。
TestController.java
package com.example.app.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.example.app.form.TestForm;
@Controller
@RequestMapping("test")
public class TestController {
@RequestMapping(method = RequestMethod.GET)
public String showInput(Model model) {
TestForm form = new TestForm();
model.addAttribute("testForm", form);
return "test/input";
}
}
TestForm form = new TestForm();
model.addAttribute("testForm", form);
Modelオブジェクトにフォームインスタンスを追加する。
Modelに追加したオブジェクトはリクエストスコープのオブジェクトとしてJSPから参照できる。
尚、上記は”testForm”という名前を指定しているが、キーを指定する必要はない。
model.addAttribute(form)と記述した場合でも、クラス名からtestFormとしてModel登録される。
入力画面
入力画面を作成する。
input.jsp
<html>
<body>
<h2>入力画面</h2>
<form:form modelAttribute="testForm">
<div>テキストを入力してください :</div>
<div>
<form:input path="text" />
</div>
<div>
<form:button>送信</form:button>
</div>
</form:form>
</body>
</html>
<form:form>タグはSpring MVCのタグライブラリ機能になる。
上記タグを使用することで、Spring MVCに関する機能を使用できるようになる。
modelAttribute属性は画面とサーバー間でデータのやりとりを行うフォームオブジェクトの名前を指定できる。
modelAttribute属性にフォーム名を記述することで、以下のように機能する。
・指定したフォームオブジェクトの値を画面にバインド
・POST送信した際に、サーバー側で使用するフォームオブジェクトに画面入力値をバインド
<form:form>タグにてmethod属性とaction属性を省略した場合、method属性はPOSTになる。
また、action属性の値は画面表示URLと同じになる。
<form:input path="text" />
上記もSpring MVCのformタグになる。
path属性にフォームのフィールド名を指定できる。
出力画面
画面入力値をそのまま出力画面に表示する。
全体像
全体的な処理のイメージは以下となる。
出力画面ではPOSTリクエストを受け付けた画面入力値を、そのまま表示する。
出力画面表示処理
出力画面を表示するための実装を行う。
コントローラー
URLとPOSTメソッドに紐づくメソッドを作成する。
TestController.java
@Controller
@RequestMapping("test")
public class TestController {
(略)
@RequestMapping(method = RequestMethod.POST)
public String ehoOutput(TestForm form) {
return "test/output";
}
}
メソッドの引数にフォームクラスを指定すると、画面入力値がバインドされたフォームオブジェクトを受け取ることができる。
また、引数で受け取ったフォームオブジェクトはModelに既に登録されている。
そのため、明示的にModelにフォームオブジェクトを追加する必要はない。
出力画面
出力画面を作成する。
output.jsp
<html>
<body>
<h2>出力画面</h2>
<div>入力したテキストは</div>
<div>
「<span><c:out value="${testForm.text}" /></span>」
</div>
<div>です。</div>
<br>
<div>
<a href="<c:url value='/index' />">トップ画面へ戻る</a>
</div>
</body>
</html>
JSTLの<c:out>タグを使用することで、特殊な記号や文字(例:<, >, & など)をサニタイズすることができる。
サニタイズすることで、クロスサイトスクリプティング (XSS) 攻撃から保護することができる。
例えば、サニタイズしない場合は画面入力値で「<script>alert(‘XSS Attack!’);</script>」と入力して出力画面を表示すると、アラートウィンドウが表示される。
サニタイズすると以下のように記号等がエスケープされるため、JSは機能しない。
<script>alert('XSS Attack!');</script>
JSTLの<c:url>タグを使用することで、URLの先頭にコンテキストパスをつけることができる。
※今回の場合は「http://localhost:8080/demo04」まで