---
title: 【Spring Advent Calendar 2013 6日目 Spring MVC + Bean Validationでフォームの未入力フィールドをnullにする spadc13
tags: []
categories: ["Programming", "Java", "Spring", "AdventCalendar", "2013"]
date: 2013-12-05T15:48:43Z
updated: 2013-12-05T15:48:43Z
---

[Spring Advent Calendar][1] 6日目の記事です。

昨日も[僕][2]でしたね。

JJUG幹事会で[@cero_t][3]さんに聞かれたので、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][4]というのが用意されています。

適用の仕方は以下のように`@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`がついていないフィールドは必須チェックがなくなるので注意です。

明日も・・・おれか？


  [1]: http://www.adventar.org/calendars/153
  [2]: /#/entries/207
  [3]: https://twitter.com/cero_t
  [4]: http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/beans/propertyeditors/StringTrimmerEditor.html
