search
LoginSignup
3

More than 3 years have passed since last update.

posted at

Bean Validation 2.0 を Java SE のプログラムに導入する

Bean Validation とは

  • Bean Validation はアノテーションを利用して入力値チェックをするAPI仕様
  • Java SE 上で実行できる
  • Java EE の 6 以降に入っている
  • Java EE 8 には Bean Validation 2.0 が入っている

Gradle で Java SE のプログラムに導入する例

build.gradle の dependencies に以下の3つを設定する。

  • javax.validation:validation-api (Bean Validation API)
  • org.hibernate.validator:hibernate-validator (Bean Validation API を実装したライブラリ)
  • org.glassfish:javax.el (Unified Expression Language を実装したライブラリ)

例えば以下の build.gradle のように記述する。
dependencies で3つの依存ライブラリを指定している。

build.gradle
plugins {
  id 'java'
  id 'application'
}

group 'com.example'
version '1.0'

sourceCompatibility = 11

repositories {
  mavenCentral()
}

dependencies {

  // https://mvnrepository.com/artifact/javax.validation/validation-api
  implementation 'javax.validation:validation-api:2.0.1.Final'

  // https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator
  runtimeOnly 'org.hibernate.validator:hibernate-validator:6.0.17.Final'

  // https://mvnrepository.com/artifact/org.glassfish/javax.el
  runtimeOnly 'org.glassfish:javax.el:3.0.1-b11'
}

application {
  mainClassName = 'com.example.App'
}

値の検証をするサンプルプログラム

Bean Validation 2.0 を使って値の検証をするサンプルプログラム。

package com.example;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Set;

public class App {

  public static void main(String[] args) {

    // バリデーターを用意
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    Validator validator = factory.getValidator();

    // 入力データを用意
    String[] list = {null, "", "1234", "12345"};

    for (var s : list) {

      // 入力データを構築
      var input = new Input();
      input.data = s;

      // バリデーション実行
      Set<ConstraintViolation<Input>> v = validator.validate(input);

      if (v.isEmpty()) {
        System.out.println(input.data + ": " + "問題ないデータです");
      } else {
        // バリデーションに引っかかったとき
        for (var vv : v) {
          System.out.println(input.data + ": " + vv.getMessage());
        }
      }
    }
  }

  private static class Input {
    @NotNull(message = "nullはダメです")
    @NotEmpty(message = "空文字列はダメです")
    @Size(max = 4, message = "4文字を超えてはダメです")
    String data;
  }
}

実行結果。

null: 空文字列はダメです
null: nullはダメです
: 空文字列はダメです
1234: 問題ないデータです
12345: 4文字を超えてはダメです

NoProviderFoundException が発生する場合

以下のようなエラーメッセージが出力される場合は、Bean Validation API を実装したライブラリがクラスパス上に見つかっていない。

javax.validation.NoProviderFoundException: Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.

Bean Validation API を実装した Hibernate Validator を使用するよう、build.gradle の dependencies に以下のように記述することで対処できる。

runtimeOnly 'org.hibernate.validator:hibernate-validator:6.0.17.Final'

NoClassDefFoundError: javax/el/ELManager が発生する場合

以下のようなエラーメッセージが出力される場合は、Unified Expression Language を実装したライブラリがクラスパス上に見つかっていない。

javax.validation.ValidationException: HV000183: Unable to initialize 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead

Hibernate Validatorでは、制約違反メッセージの動的な式を評価するために、Unified Expression Language(JSR 341)の実装も必要となっている。
Java EE コンテナなどには含まれているが、Java SE では明示的に導入が必要。
org.glassfish の javax.el が JSR 341 のリファレンス実装とのことなのでこれを導入すればいい。
build.gradle の dependencies に以下のように記述することで対処できる。

runtimeOnly 'org.glassfish:javax.el:3.0.1-b11'

参考資料

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3