@NotNull/@NotEmpty/@NotBlankの違い
JavaEE6から新しい仕様BeanValidation(JSR303)が導入されています。
BeanValidationではアノテーションでユーザ入力チェックを定義することができます。Struts1.xではvalidation.xmlの記述量が多く、度重なるタイプミスとランタイムエラーに苦しめられてきましたが、アノテーションのタイプミスはコンパイル時にチェックされるので、苦しみが軽減されています。
JSF2.0と組み合わせて使用するとき、「必須入力チェック」について同じような意味を持つアノテーションがいくつかあったので、違いを以下にまとめておきます。
以下のようなPersonクラスを定義し、各アノテーションの挙動の違いを確認します。
import javax.validation.constraints.NotNull; import org.hibernate.validator.constraints.NotBlank; import org.hibernate.validator.constraints.NotEmpty; public class Person { @NotNull private String firstName; @NotEmpty private String middleName; @NotBlank private String lastName; // getterとsetterは省略 }
このPersonクラスに対して、以下のようなユニットテストを書いてみます。
このテストコードの結果は興味深いことに"グリーン(成功)"です。
public class PersonValidatorTest { private static Validator validator; @BeforeClass public static void init() { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); } @Test public void nameIsRequired() { Person person = new Person(); person.setFirstName(""); // @NotNullは空文字エラーにする? person.setMiddleName(" "); // @NotEmptyは空白のみをエラーにする? person.setLastName(" "); // @NotBlankは空白のみをエラーにする? Set<ConstraintViolation<Person>> constraintValidation = validator.validate(person); // エラーは1件だけ(@NotBlankの部分) assertThat(constraintValidation.size(), is(1)); } }
挙動をまとめると、以下のようになります。×はチェックエラー、○は許可を表します。
Null | ""(空文字) | 空白のみ | |
---|---|---|---|
@NotNull | × | ○ | ○ |
@NotEmpty | × | × | ○ |
@NotBlank | × | × | × |
JSF2.0と組み合わせて使う場合に注意したいのは、「必須入力チェック」に対してJavaEE標準で用意されている@NotNullを使うと、デフォルトではフォームに何も入力されていない場合(空文字となる)、Validationをパスしてしまうことです。
以下の設定をweb.xmlに加えると、@NotNullでも必須入力チェックが可能です。
フォームに何も入力されていない場合、空文字ではなくnullと見なされます。
<context-param> <param-name> javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL </param-name> <param-value>true</param-value> </context-param>
HibernateValidatorの独自実装である@NotBlankを使わなくて済むので便利な設定です。