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等を選択
動作確認に必要なもの
- JDK 25
- IDE、もしくは開発エディタ
- ブラウザ
- Postman : 更新系リクエストを動作確認したい方
- DB : MySQL Community Server 8.0系
サンプルコードプロジェクト 必要なライブラリ
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=updateEntityクラスに検証アノテーションを追加
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の開発方法を学ぶコースを開催しています。