Spring Data RESTでJakarta Validationによる入力検証を行う

Spring Data RESTに関する連載の2回目です。
前回は、商品の全件取得、ID指定での取得、追加、更新、部分更新、削除の機能をもつRESTful WebサービスをSpring Data RESTを使って作成しました。
今回は、このアプリケーションに、Jakarta Validationを使って入力検証を行う機能を追加します。

Spring Data REST に関する連載として、今後第3回以降の記事も紹介する予定です。

  • 第1回 : Spring Data REST で RESTful Webサービスを作る
  • 第2回(今回) : Spring Data RESTでJakarta Validationによる入力検証を行う
  • 第3回 : Spring Data RESTで条件検索に対応した一覧取得を行う
    • 商品名の部分一致検索や、価格の指定検索など
  • 第4回 : Spring Data RESTで関連したエンティティのデータも一括して取得する
  • 第5回 : 画像のアップロードに対応したRESTful Web APIを作成する

サンプルコード

完成版のサンプルコードは、 以下のGitLabリポジトリからダウンロードしてください。
ダウンロード

手順: [コード]ボタン クリック⇒ソースコードをダウンロード⇒zip等を選択

動作確認に必要なもの

サンプルコードプロジェクト 必要なライブラリ

Jakarta Validationを利用する場合、以下のライブラリが必要です。

  • Validation : Jakarta Validation仕様および、その実装である Hibernate Validatorを使うために必要です。

また、前回の記事で紹介したライブラリも必要です。

  • Spring Web : WebアプリやREST Web サービスを作る際に必要
  • Spring Data JPA : JPAを使ってEntityをDBに永続化するためのライブラリ
  • Rest Repositories : Spring Data RESTのライブラリ
  • MySQL Driver : サンプルアプリでは、DBとしてMySQLを使うため

データベースの作成

アプリケーションからアクセスするデータベースおよびユーザーを作成しておきます。
create-schema-spring.sql はサンプルコードの直下にあります。こちらのSQLを実行してください。

DROP DATABASE IF EXISTS itemsdb;
CREATE DATABASE itemsdb CHARACTER SET utf8mb4;
DROP USER IF EXISTS 'user-itemsdb';
CREATE USER 'user-itemsdb' IDENTIFIED BY 'P@ssw0rd';
GRANT ALL PRIVILEGES ON itemsdb.* to 'user-itemsdb';
USE itemsdb;
SHOW DATABASES;

設定ファイルの準備

src/main/resources/application.properties ファイルの内容は、前回と同じです。

spring.application.name=items

# DataSource
spring.datasource.url=jdbc:mysql://localhost:3306/itemsdb
spring.datasource.username=user-itemsdb
spring.datasource.password=P@ssw0rd
spring.jpa.database=mysql
spring.sql.init.encoding=utf-8

# for Spring Data REST : root path
spring.data.rest.basePath=/api

# for Jakarta Persistence
# spring.jpa.hibernate.ddl-auto
#   none   : 何もしない
#   update : アプリ起動時に、Entityに対応するテーブルがなければ作成。あればそのまま。
#   create : アプリ起動時に、Entityに対応するテーブルがなければ作成。あればデータを削除。
spring.jpa.hibernate.ddl-auto=update

Entityクラスに検証アノテーションを追加

Entityクラスに、Jakarta Validationのアノテーションを追加することで、入力値の検証が可能になります。

com.example.items.entity.Item ファイル

/// 商品を表すエンティティクラス
@Entity
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;     // 商品ID (主キー、自動採番:AUTO_INCREMENT)

    @NotBlank
    @Size(min = 1, max = 40)
    private String name;    // 商品名

    @Min(0)
    private Integer price;  // 価格

    // setter/getter/toString/equals/hashCodeメソッド 省略
}
  • @NotBlank : null、空文字、半角スペースのみを許可しない
  • @Size : 文字列長の指定
    • ここでは、1文字以上40文字以下を設定
  • @Min : 最小値の指定
    • ここでは、0以上を設定

イベントリスナーとしてバリデータの登録

Mainクラスcom.example.items.ItemsApplicationに、バリデータを登録するためのイベントリスナーを追加します。

@SpringBootApplication
public class ItemsApplication {

	public static void main(String[] args) {
		SpringApplication.run(ItemsApplication.class, args);
	}

	@Configuration
	static class DataRestConfig implements RepositoryRestConfigurer {

		private final org.springframework.validation.Validator validator;

		DataRestConfig(org.springframework.validation.Validator validator) {
			this.validator = validator;
		}

		@Override
		public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
			// リポジトリに新規追加(POSTの際)する前に入力検証を行う設定
			validatingListener.addValidator("beforeCreate", validator);
			// リポジトリを更新(PUT/PATCHの際)する前に入力検証を行う設定
			validatingListener.addValidator("beforeSave", validator);
		}
	}

}
  • RepositoryRestConfigurer
    • Spring Data Rest の設定を構成したり、カスタマイズするためのインタフェース。
  • org.springframework.validation.Validator
    • このI/Fのvalidateメソッドの引数にJakarta Validationのアノテーションが付いたクラスのインスタンスを渡すことで、入力検証が行われる。
  • configureValidatingRepositoryEventListenerメソッド
    • このメソッドをオーバーライドすることで、バリデータを追加できる。
  • ValidatingRepositoryEventListener
    • このリスナーにRepositoryEventとバリデータを登録することで、指定したタイミングで入力検証を行なえる。

変更するソースコードは、この2ファイルのみです。

実行・動作確認

アプリケーション(com.example.items.ItemsApplication)を起動します。

新規登録(POST)の入力検証

更新系(POST/PUT/PATCH/DELETE)のリクエストは、前回同様Postmanを使います。今回は、入力検証が行われることを確認してみましょう。

HTTPメソッド : POST
URL : http://localhost:8080/api/items

リクエストボディに、登録したい情報を JSON 形式で指定します。サンプルコードの /WebAPI呼び出し/入力検証エラー フォルダにある items-post-error1.json 〜 items-post-error2.json のデータを使って、入力検証が行われることを確認してみましょう。

/WebAPI呼び出し/入力検証エラー/items-post-error1.json

{
  "name": "",
  "price": -1
}

/WebAPI呼び出し/入力検証エラー/items-post-error2.json

{
  "name": "12345678901234567890123456789012345678901",
  "price": -1
}

それぞれのリクエストの実行結果は以下のようになります。

/WebAPI呼び出し/入力検証エラー/items-post-error1.jsonの実行結果

{
    "errors": [
        {
            "entity": "Item",
            "invalidValue": -1,
            "message": "0 以上の値にしてください",
            "property": "price"
        },
        {
            "entity": "Item",
            "invalidValue": "",
            "message": "1 から 40 の間のサイズにしてください",
            "property": "name"
        },
        {
            "entity": "Item",
            "invalidValue": "",
            "message": "空白は許可されていません",
            "property": "name"
        }
    ]
}

/WebAPI呼び出し/入力検証エラー/items-post-error2.jsonの実行結果

{
    "errors": [
        {
            "entity": "Item",
            "invalidValue": "12345678901234567890123456789012345678901",
            "message": "1 から 40 の間のサイズにしてください",
            "property": "name"
        },
        {
            "entity": "Item",
            "invalidValue": -1,
            "message": "0 以上の値にしてください",
            "property": "price"
        }
    ]
}

更新(PUT)・部分更新(PATCH)の入力検証

リソースの更新は PUTでリクエストします。
リソースの部分更新は PATCHでリクエストします。
URL : http://localhost:8080/api/items/(idを指定)

例. http://localhost:8080/api/items/1 (id=1のリソースを指定)

サンプルコードの /WebAPI呼び出し/入力検証エラー フォルダにある items-put-error1.json 〜 items-put-error2.json、items-patch-error1.json 〜 items-patch-error2.json のデータを使って、入力検証が行われることを確認してみましょう。

おわりに

Spring Data RESTでJakarta Validationによる入力検証を行う方法を紹介しましたが、いかがでしょうか?
Spring Data RESTを使う場合、入力検証を行うためにコントローラークラスやサービスクラスを作成する必要がなく、Entityクラスにアノテーションを付与するだけで入力検証が行えることを学びました。

カサレアルでは、Springの開発方法を学ぶコースを開催しています。

Spring研修一覧

 

--------------------------
開発支援・技術研修のご要望・ご相談はこちらから
--------------------------
【この技術ブログを読んだエンジニアの皆様へ】
カサレアルブログをお読みいただき、ありがとうございます!

私たちは、常に新しい技術に挑戦し、ユーザーのニーズに応えるサービスを提供しています。
もし、当社の技術への情熱や、会社・チーム・社員の雰囲気に共感いただけたなら、
ぜひ私たちと一緒に働きませんか?
現在、株式会社カサレアルでは事業拡大に伴い、新たな仲間となるエンジニアを積極的に募集しています。

少しでも興味をお持ちいただけましたら、まずは弊社のことを知っていただけると嬉しいです。
▼採用サイト
https://www.casareal.co.jp/recruit/career
▼社員インタビュー
https://hrmos.co/pages/casareal/jobs/0000016
▼エンジニアの仲間になる! エントリーはこちらから
https://hrmos.co/pages/casareal/jobs

皆様のエントリーを心よりお待ちしています!

Raspberry Piで作成したNASのバックアップについて

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

コメント ※

名前 ※

メール ※

サイト