LoginSignup
5
3

More than 3 years have passed since last update.

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

Posted at

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'

参考資料

5
3
0

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
  3. You can use dark theme
What you can do with signing up
5
3