SpringMVCでFormのバリデーションどうやるか?っていうのを調べてたら、
どうやらJSR 303: Bean Validationってのでやりくりするみたいです。
Spring3のドキュメントみてもそんな風に書いてあります→ 5.7 Spring 3 Validation
ということで、さっそく実装してみます。
入力はHTMLから普通にFormをSubmitするわけなんですが、Springのタグラリブラリ使って、
modelAttribute=”hoge”って感じでサーバ側に送ってあげます。
■ 入力画面のJSP
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <%@ page session="false" %> <html> <body> <form:form modelAttribute="hoge" method="POST" action="/aaa/hoge/regist"> <input type="text" name="hogeId" value="999" /> <input type="text" name="hogeStr" value="hogehogehoge" /> <input type="submit" value="Save" /> </form:form> </body> </html>
■ 受け取るコントローラ
以下のようにコレといってなんにもしないでバリューオブジェクトにセットしてくれて
Controllerから扱えます。楽チンです。
@RequestMapping(value = "/hoge/regist", method = RequestMethod.POST) public String regist(Hoge hoge, Locale locale, Model model) { logger.info(String.valueOf(hoge.getHogeId())); logger.info(hoge.getHogeStr());
■ Validation
お仕事でシステム作ってると、必ず必要になってくるのがバリデーションです。
↓とかみるとHibernateのValidatorを使おうって感じみたいです。
http://d.hatena.ne.jp/yamkazu/20110206/1296985545
http://blog.jteam.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring/
ってことで、以下のようにJBossのリポジトリ足してhibernate-validatorのjarの定義入れます。
#JBossもHibernateも使わないのになんかちょっとシャクですが。。
~略~ <repository> <id>JBoss Repo</id> <name>JBoss Repo</name> <url>https://repository.jboss.org/nexus/content/repositories/releases</url> </repository> ~略~ <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.2.0.Final</version> </dependency>
バリデーションに関しては、コントローラーで受け取る引数に、
以下のように@Validアノテーションを入れる感じになります。お手軽。。
public String regist(@Valid Hoge hoge, Locale locale, Model model) {
で、バリューオブジェクトに以下のようなアノテーションを付けてみます。
IDは99がMAXで、文字列はNotNullですよ、と。
public class Hoge { @Max(99) private int hogeId; @NotNull private String hogeStr;
IDに99、と文字列にhogehogehogeを入力してサブミットすると、
以下のように普通に値が取れますが、
INFO : com.shinodogg.HogeController - HOGE Regist Start INFO : com.shinodogg.HogeController - 99 INFO : com.shinodogg.HogeController - hogehogehoge
IDを100にすると、、以下のようにバリデーションエラーになります。
例外 org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'hoge' on field 'hogeId': rejected value [100]; codes [Max.hoge.hogeId,Max.hogeId,Max.int,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [hoge.hogeId,hogeId]; arguments []; default message [hogeId],99]; default message [must be less than or equal to 99] org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560) javax.servlet.http.HttpServlet.service(HttpServlet.java:641) javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 原因 org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'hoge' on field 'hogeId': rejected value [100]; codes [Max.hoge.hogeId,Max.hogeId,Max.int,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [hoge.hogeId,hogeId]; arguments []; default message [hogeId],99]; default message [must be less than or equal to 99] org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:810)
後は、500エラーを返すのではなく、ちゃんとキャッチしてメッセージをそれっぽいのにして、
クライアントに返してやる必要がありますが、そこから先は @atushi がイイ感じにやりくりしてくれるでしょうw
ちなみに@atushiは、iFieldRecという↓なiPhoneアプリを最近リリースしましたw
[youtube https://www.youtube.com/watch?v=Vqpo1ONC_Lg&w=560&h=315]
85円で買えますので是非どうぞw↓
http://itunes.apple.com/en/app/ifieldrec/id456579902?mt=8
毎日コミュニケーションズ
売り上げランキング: 600
コメント
宣伝ありがとうございますmm
SFに行っている間、日本でなんとかNG○○を形にします!