Spring Advent Calendar 6日目の記事です。
昨日も僕でしたね。
JJUG幹事会で@cero_tさんに聞かれたので、Advent Calendarのネタとして答えておく。
Spring MVCでは文字列の入力フィールドに未入力の状態でフォームを送信した場合、 デフォルトでは、フォームオブジェクトのフィールドにnullではなく、空文字がバインドされます。(Integerフィールドだとnullがバインドされます)
以下のようなフォーム用JavaBeanを考えます。
public class HogeForm {
@NotNull
@Size(min = 1)
private String username;
//...
}
usernameフィールドを未入力で送信し、Bean ValidationでバインドされたHogeForm
をチェックすると、usernameフィールドには空文字が入るので、@NotNull
のエラーではなく、@Size
によるエラーが発生します。
ちなみに@NotNull
と@Size(min=1)
をまとめたのがHibernate Validatorで提供されている@NotEmpty
(非標準)です。
通常は文字列フィールドの必須チェックは@NotNull
+@Size
または@NotEmpty
でいいですが、これだと「未入力はOKだけど、入力されている場合は4文字以上で」というルールを表現できません。よくある要件だと思います。
この場合どうするかというと、一つの手段としては@EmptyOrGreaterThan
みたいなアノテーションをつくるってのでもありですが、他の組み合わせパターンもでてくるとパターンごとにつくらないといけないのでちょっと面倒です。
もう一つのやり方として、Spring MVCのControllerの初期処理で空文字をnullにしてしまう、ということもできます。この処理のためにStringTrimmerEditorというのが用意されています。
適用の仕方は以下のように@InitBinder
をつけたメソッドでStringTrimmerEditor
を登録するだけです。
@Controller
@RequestMapping("hoge")
public class HogeController {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
// 略
}
Controller毎に設定すれば、設定したControllerにのみ上記の処理が適用されます。
Spring3.2から導入された@ControllerAdvice
を使うと全Controllerに適用できます。これはプロジェクトで方針を決めて使用する必要があります。
@ControllerAdvice
public class HogeControllerAdvice {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
// 略
}
‘StringTrimmerEditor‘の設定があれば、以下のアノテーションで「未入力はOKだけど、入力されている場合は4文字以上で」というルールを表現できます。
public class HogeForm {
@Size(min = 4)
private String username;
//...
}
Bean Validationは基本nullは正常値なので、@NotNull
がついていないフィールドは必須チェックがなくなるので注意です。
明日も・・・おれか?