バリデーションの利用
バリデーション用に新しいプロジェクトを作成する。
プロジェクトの作成と初期設定
プロジェクト名: Memo
テンプレート: Simple Spring Web Maven
プロジェクトを作成したら、以下を実行。
- [Maven]-[プロジェクトの更新]
- [実行]-[maven install]
文字化け対策のために、web.xml を編集。
最後の <web-app> タグの手前に以下の内容を追加。
src/main/webapp/WEB-INF/web.xml
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
使用するパッケージ名を mvc-config.xml に設定。
src/main/webapp/WEB-INF/mvc-config.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="jp.abc"/> <mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- Example: a logical view name of 'showMessage' is mapped to '/WEB-INF/jsp/showMessage.jsp' --> <property name="prefix" value="/WEB-INF/view/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
サーバータブの Tomcat7 サーバーに Memo プロジェクトを追加して Tomcat7 サーバーを再起動。
http://localhost:8080/Memo/ にアクセスすれば、click to enter が表示される。
FormModelの作成
javaリソースの src/java/main を右クリックし、クラスを新規作成する。
パッケージ名: jp.abc
クラス名; FormModel
FormModel.java
package jp.abc; import java.util.Date; public class FormModel { private String item; private Integer price; private Date buydate; private String memo; public String getItem() { return item; } public void setItem(String item) { this.item = item; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public Date getBuydate() { return buydate; } public void setBuydate(Date buydate) { this.buydate = buydate; } public String getMemo() { return memo; } public void setMemo(String memo) { this.memo = memo; } }
ビューテンプレートの変更
showMessage.jsp を以下のように変更する。
<!DOCTYPE html> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta charset="utf-8"> <title>${title}</title> <style type="text/css"> h1 { font-size: 16pt;background-color: #ccccff;padding:3px; } p { color: #000066; } </style> </head> <body> <h1>${title}</h1> <p>${message}</p> <table> <form:form modelAttribute="formModel"> <tr> <td><form:label path="item">商品名</form:label></td> <td><form:input path="item" size="20" /></td> </tr> <tr> <td><form:label path="price">金額</form:label></td> <td><form:input path="price" size="20" /></td> </tr> <tr> <td><form:label path="memo">メモ</form:label></td> <td><form:textarea path="memo" cols="20" rows="5" /></td> </tr> <tr><td><input type="submit"></td></tr> </form:form> </table> <hr /> <c:if test="${datalist != null}" > <table border="1"> <tr><th>商品名</th><th>価格</th></tr> <c:forEach var="obj" items="${datalist}" varStatus="status"> <tr> <td>${obj.item}</td> <td>${obj.price}</td> </tr> </c:forEach> </table> </c:if> </body> </html>
コントローラを作成する
買い物メモのコントローラを作成する。
テキストでは MyAppController を再利用しているが、ここでは新しく MemoController を作成する。
※開発する際に、名前は重要!
Javaリソースの src/java/main の下にある jp.abc パッケージを右クリックして [新規]-[クラス] を選択。
名前: MemoController
まずは、GET メソッドに対応する部分だけ入力する。
MemoController.java
package jp.abc; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class MemoController { private List<FormModel> buylist = new ArrayList<FormModel>(); @RequestMapping(value = "/list", method = RequestMethod.GET) public String list(Model model) { model.addAttribute("title", "Sample"); model.addAttribute("message", "買い物メモです。"); FormModel fm = new FormModel(); model.addAttribute("formModel", fm); model.addAttribute("datalist", buylist); return "showMessage"; } }
http://localhost:8080/Memo/list にアクセスする。
買い物メモの画面が表示されればOK。
次に POST メソッドに対応する部分を実装する。
MemoController.java
@RequestMapping(value = "/list", method = RequestMethod.POST) public String form(@ModelAttribute FormModel formModel, BindingResult result, Model model) { buylist.add(formModel); model.addAttribute("title", "Sample"); String res = "<ol>"; res += "<li>" + formModel.getItem() + "</li>"; res += "<li>" + formModel.getPrice() + "</li>"; res += "<li>" + formModel.getMemo() + "</li>"; res += "<li>" + Calendar.getInstance().getTime() + "</li>"; res += "</ol>"; res += "<p>" + buylist.size() + "</p>"; model.addAttribute("message", res); model.addAttribute("datalist", buylist); model.addAttribute("formModel", new FormModel()); return "showMessage"; }
バリデーション用ライブラリをロードする
パッケージエクスプローラで、Memoプロジェクトの一番下にあるファイル pom.xml を開く。
エディタの下にある「pom.xml」タブを選択する。
ファイルの最後の <dependencies> の手前に以下の内容を追加する。
pom.xml
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.0.1.Final</version> </dependency> </dependencies> </project>
保存すると、自動的にプロジェクトがビルドされ、ライブラリをダウンロードしてくれる。
JSPの変更
showMessage.jsp にエラーメッセージを表示するためのタグを追加する。
showMessage.jsp
<form:form modelAttribute="formModel"> <tr><td></td><td><form:errors path="*" element="div" /></td></tr> <tr> <td><form:label path="item">商品名</form:label></td> <td><form:input path="item" size="20" /></td> </tr>
コントローラの変更
GETメソッドはバリデーションは関係なので、POSTメソッドを処理するメソッドを変更する。
まず、バリデーションの対象となる最初の引数 FormModel に @Valid アノテーションを追加する。
MemoController.java
@RequestMapping(value = "/list", method = RequestMethod.POST) public String form(@Valid @ModelAttribute FormModel formModel, BindingResult result, Model model) {
エラーがあったときには、異なるタイトルとメッセージを表示するように変更する。
判断は、BindingResult#hasErrors()メソッドを使用する。
MemoController.java
@RequestMapping(value = "/list", method = RequestMethod.POST) public String form(@Valid @ModelAttribute FormModel formModel, BindingResult result, Model model) { if (result.hasErrors()) { model.addAttribute("title", "Sample [ERROR]"); model.addAttribute("message", "値を再チェックしてください"); } else { buylist.add(formModel); model.addAttribute("title", "送信内容"); String res = "<ol>"; res += "<li>" + formModel.getItem() + "</li>"; res += "<li>" + formModel.getPrice() + "</li>"; res += "<li>" + formModel.getMemo() + "</li>"; res += "<li>" + Calendar.getInstance().getTime() + "</li>"; res += "</ol>"; res += "<p>" + buylist.size() + "</p>"; model.addAttribute("message", res); model.addAttribute("formModel", new FormModel()); } model.addAttribute("datalist", buylist); return "showMessage"; }
エラーメッセージのカスタマイズ
エラーメッセージを変更するには、アノテーションに message 引数を追加するのが簡単。
FormModel.java
public class FormModel { @NotEmpty(message="商品名は必須です。") private String item; @Min(value=0, message="{value}以上の値が必要です。") private Integer price; private Date buydate; private String memo;
個別にメッセージを表示する
現状では1箇所にまとめてエラーメッセージを表示しているが、これを入力フィールド毎に変更できる。
<form:errors> タグの path 属性の * を、それぞれの変数名で指定すればよい。
showMessage.jsp
<form:form modelAttribute="formModel"> <tr> <td><form:label path="item">商品名</form:label></td> <td><form:input path="item" size="20" /> <form:errors path="item" cssStyle="color:red" /></td> </tr> <tr> <td><form:label path="price">金額</form:label></td> <td><form:input path="price" size="20" /> <form:errors path="price" cssStyle="color:red" /></td> </tr> <tr> <td><form:label path="memo">メモ</form:label></td> <td><form:textarea path="memo" cols="20" rows="5" /> <form:errors path="memo" cssStyle="color:red" /></td> </tr> <tr><td><input type="submit"></td></tr> </form:form>