09.Binderの初期化について
(パラメタからモデルへの型変換)
概要
Binderによる型変換はSpringの一般的な機能です。
ここでは、リクエストパラメタを様々な型に変換する方法を中心に見ていきます。
グローバルなBinderの初期化にも触れてみたいと思います。
※概要については以下の記事を参照ください
型変換初期化メソッド(initBinder)について
型変換の方法を設定するには、Binderを初期化します。
型変換初期化をするためのメソッドは、@InitBinderアノテーションをつけたメソッドです。
メソッドはBinderを引数にとり、メソッド内で初期化します。
InitBinderメソッドで行う処理は、たいていの場合、主に以下の2つです。
・型変換の方法の設定
・上書きを許可するプロパティの設定
【記述例(リクエストパラメタを日付型に変換しています)】
@InitBinder("form")
public void initBinderForm(WebDataBinder binder) {
//バインドするときの日付のフォーマット指定。
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, "user.upDate", new CustomDateEditor(dateFormat, true));
//Userオブジェクトのうち、user.ageとuser.upDateパラメタのみを受け取るようにする場合
binder.setAllowedFields("user.age", "user.upDate");
}
型変換の方法の設定
型変換の設定方法は、PropertyEditorクラスをregisterCustomEditor()メソッドで設定していくという形をとります。
PropertyEditorクラスは型変換の方法を定義したクラスです。自作しても良いですが、すでにいくつか用意されています。
また、いくつかはデフォルトで設定されているので、すべてを設定する必要がありません。
おそらくDateとNumberの書式を指定するために登録するくらいかと思います。
【設定の方法】
registerCustomEditor()は2種類用意されています。
上記の記述例のように、プロパティ名("user.upDate")を指定する方法と、全てのDate型に対して設定する方法です。
単純に、プロパティ名の引数を削除して、
registerCustomEditor(型, PropertyEditor)という記述にすればプロパティ名は関係なくすべての型に対して設定されます。
【PropertyEditor型変換クラス一覧(Springドキュメントからの引用)】
不正なリクエストパラメタを拒否する方法
既に他の記事で書いていますが、Binderでは不正なリクエストパラメタを無視する機能があります。
具体的には、許可するプロパティ名を指定するか、拒否するプロパティ名を指定するか、2つの方法があります。
【記述例】
binder.setAllowedFields("user.age", "user.upDate");
binder.setDisallowedFields("user.feeId");
binder.setDisallowedFields("menu.*", "*dis*"); //ワイルドカードも使用できます
メソッド名がそのまま意味をなしているのでだいたい予想がつくかと思いますが、
setDisallowedFieldsが拒否するプロパティ名を指定するメソッドです。
パラメタ名のプレフィックスを指定する方法
パラメタ名の先頭とモデルのプロパティ名が一致しないケースがありえます。
例えば、パラメタ名に"form.user.age", "form.user.upDate"のように、すべて"form."がついているようなケースです。
この場合、getForm()/setForm()というメソッドが存在しない場合、リクエストパラメタの値がバインドされません。
こんな時はプレフィックスを設定します。
【記述例】
binder.setFieldDefaultPrefix("form.");
こうすることで、パラメタ"form.user.age"が、form.getUser().setAge(21) に設定されます。
Validatorの設定
妥当性チェックもBinderの仕事ですので、当然ながらValidatorも設定できます。
妥当性チェックについては他の記事で記述しますので、ここでは割愛します。
グローバルなBinderの初期化
もし全体を通して同じ設定の場合、Controller毎にBinderを初期化するのは大変です。
もちろんSpringMVCでは、グローバルな初期化方法も用意されています。
その方法を見てみます。
WebBindingInitializerインターフェース
【追記:2018/6/23】
Spring3.2以降、ControllerAdviceを使用するらしいので、記事を修正しました。
アノテーションを使用するので、XMLファイルに<mvc:annotation-driven />の記述は必要です。
実は、WebBindingInitializerの派生クラスを作成するだけです。
実際のコードと、Spring設定ファイルへの記述方法を見る方が早いので、さっそく見てみましょう。
【サンプル(クラス): com.sample.contoller.GlobalBindingInitializer】
@ControllerAdvice
@Component
public class GlobalBindingInitializer implements WebBindingInitializer {
@InitBinder
@Override
public void initBinder(WebDataBinder binder, WebRequest req) {
//Dateの書式を設定します
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
}
Dateの書式の設定の仕方は、Controllerのときと同じです。
【サンプル(Spring設定ファイル)】
<bean class="com.sample.contoller.GlobalBindingInitializer"/>
※Spring3.2以前を使用している場合は、org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapterを
bean設定して、webBindingInitializerプロパティに上記クラスを設定する方法も動作します。
これだけでうまく動くはずです。
Created Date: 2012/04/08