はじめに

こんにちは。テクノロジー&エンジニアリングセンターの羽部です。

今回は、Nablarch解説書に記載されていない情報の補完を目的に記事を書きました。「ここは実際どうするの?」といった情報をお伝えします。

システムの外からデータを受け取った時、欠かせないのがバリデーションです。一口にバリデーションといっても、桁数や文字種をチェックしたり、項目間で整合性が取れているかチェックしたりといくつかの種類があります。また、バリデーションだけではなく二重サブミットチェックといったチェックもあります。

それらをどのクラスにどうやって実装するのかも悩みどころです。Nablarchの場合、実現方法を何通りか考えることができ、この悩みを深めています。

そこで今回、バリデーションやチェックをNablarchではどこにどう実装するのか、ウェブアプリケーションを想定して一例を紹介します。

なお、Nablarchはバリデーション(入力値のチェック)を行う方法として、以下の2種類の機能を提供しています。

本記事では、Nablarchが推奨するBean Validationを対象とします。

本記事で扱うバリデーションやチェック

一口にバリデーションと言っても、実際に何をチェックするのか、というバリデーションの種類はいくつかあります。今回は、以下のバリデーションを扱います。

種類 説明
単項目 入力値の桁数や文字種、形式などが妥当なものかチェックする。
項目間 2つ以上の入力値の関係が妥当かチェックする。例えば、パスワード欄とパスワード(確認)欄の2つの入力値が一致するかなど。
データ相関 入力値がシステムの状態に適合するかチェックする。例えば、入力された部署が部署マスタに存在するかや、新規ユーザ登録で入力されたログインIDが既に登録されていないかなど。

また、チェックについては、以下の2つのチェックを扱います。

  • 二重サブミット
  • 楽観的排他制御

各種バリデーションやチェックの実装方法

各種バリデーションやチェックをどこにどう実装すべきなのか、下表にまとめてみました。

種類 どこに 実装方法 その理由
単項目 フォームクラス アノテーション(@Domainなど)。解説書はこちら アクションクラスでは、セキュリティ上の理由から、バリデーションされていない入力値を扱うべきではありません。このため、アクションクラスで入力値を使用する前にバリデーションを実行する必要があります。
項目間 フォームクラス 項目間バリデーション用のメソッドを作成し、これに@AssertTrueアノテーションをつける。解説書はこちら 入力値に関するバリデーションはフォームクラスに実装することで、保守性が向上します。
データ相関 アクションクラス チェックロジックを記述する。 データ相関では、データベースアクセスを行う場合が多くあります。フォームクラス内でデータ相関バリデーションを行った場合、バリデーション前の安全ではない値を使って、データベースアクセスを行うことになります。これは、SQLインジェクションなどの脆弱性の原因となります。
二重サブミット JSPとアクションクラス JSPでは、n:formタグのuseToken属性をtrueに、サブミット用のタグのallowDoubleSubmission属性をfalseに設定する。あわせてアクションクラスでは、二重サブミットを防止したいメソッドに@OnDoubleSubmissionを設定する。解説書はこちら 自前で実装するのではなく、Nablarch提供機能を使用します。また、次の理由からサーバサイド、クライアントサイド両方の2重サブミット防止策を併用すべきです。
サーバサイドのみ使用した場合は、ダブルクリックによりリクエストが2回送信される可能性があります。この時サーバの処理順によっては、2重サブミットエラーが返され、ユーザに処理結果が返されない恐れがあります。
クライアントサイドのみ使用した場合は、リクエストを重複して処理する恐れがあります。
楽観的排他制御 アクションクラス UniversalDaoが提供する楽観的ロック機能を利用する。解説書はこちら UniversalDaoで更新処理を行う際にはエンティティクラスを引き渡します。この時、エンティティクラスのバージョンカラム(具体的には、@Versionアノテーションが指定されているプロパティ)の値とDB側の同カラムの値が一致していなければ、UniversalDaoは排他制御の例外を発生させます。この動作を利用します。

おわりに

いかがだったでしょうか。どこでどうやってバリデーションやチェックを実装するんだろう、というお悩みの解決に役立てられたら幸いです。


本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。