より複雑な入力チェックを実装する方法
先ほど示しましたリスト5のActionクラスにて、名前(name)のチェックでは指定された文字列(prohibitionNames)を含んではいないかをチェックする機能(リスト中(A)の部分)、パスワード(password)のチェックでは、入力された名前にパスワードが含まれていないかをチェックする機能(リスト中(B)の部分)を実装しています。
OVal Frameworkには設定のみで書くには困難なチェック内容を、Javaのコードでチェックロジックを記述し実装する機能も設けられており、実装内容の複雑さにあわせて作成方法が2種類用意されています。
- 単一項目の入力チェックを拡張する @ValidateWithMethod
- 複数項目に渡るチェックを行う @CheckWith
これらの利点は、Javaのコードで拡張した入力チェック内容もOVal Frameworkに統合して管理させることができますので、入力チェックの実装箇所を1つのクラスにまとめることができます。
では、その詳細を説明していきましょう。
(1)単一項目の入力チェックを拡張する @ValidateWithMethod
単一項目の入力チェックを拡張するのであれば@ValidateWithMethodを使います。サンプルでの適用箇所を以下に示します。
public class SampleModel {
…(中略)…
@ValidateWithMethod(methodName = "isValidName",
parameterType = String.class , message="usermodel.input.name.prohibit") // (A)
private String name
/** 入力禁止の名前 */
private String[] prohibitionNames = {"aaa","bbb","ccc","ddd","eee"};
…(中略)…
private boolean isValidName(String name) {
for ( String prohibition:prohibitionNames) {
// 引数で渡された値が入力禁止の名前に登録されている文字列を含んでいた場合はfalse
if ( name.contains(prohibition)) {
return false;
}
}
return true;
}
@ValidateWithMethod内で設定するパラメータを表にしたものが次の表です。
| 名前 | 型 | 説明 |
| methodName | String | 入力チェック内容を実装しているメソッド名 |
| parameterType | Class | 入力チェック対象のフィールドのクラス |
| message | String | 入力チェックエラーと判定したときに出力されるメッセージ |
また@ValidateWithMethodを利用する場合には次のルールを必ず守ります。
- @ValidateWithMethodのmethodNameに宣言されたメソッド(以降、チェックメソッド)を使って、入力チェックを実装
- チェックメソッドは必ずbooleanで結果を返す
- ランタイム例外を検出した場合でも、想定されるものであればメソッド内で完結する
(2)複数項目に渡るチェックを行う @CheckWith
入力項目には、複数の項目の関係をみて1つのチェックとするものもしばしば存在します。例えば年月日を別々の入力項目として入力するものや、開始期間~終了期間を入力するもの、同じ項目を入力して欲しくない項目など、複数項目にまたがる入力チェックを使うことがあります。OVal Frameworkには単一項目だけでなく、複数項目の入力チェックもサポートしており、Javaのコードで実装できる仕組みも用意しています。
では先ほどのサンプルから実装箇所を抜粋し、内容を見てみましょう。
public class SampleModel {
…(中略)…
@CheckWith(value=NameAndPasswordCheck.class ,message="usermodel.input.name.containpassword") // (B)
private String password;
…(中略)…
private static class NameAndPasswordCheck implements CheckWithCheck.SimpleCheck {
/**
* 入力された名前にパスワードが含まれていないかをチェックする。
* ※CheckWithCheck必須実装メソッド。
* @param validatedObject チェック対象インスタンス。
* @param value パラメータ値。
*/
public boolean isSatisfied(Object validatedObject, Object value) {
// CheckWithCheckを呼び出しているフィールドに指定された値が空でないかをチェックする。
// もし空であればチェック対象にしないので、ここではtrueを返してチェックを行わない。
String nullCheck = (String)value;
if ( nullCheck == null || nullCheck.equals("")) return true;
// チェック対象フィールドを取り出す
String name = ((SampleModel) validatedObject).name;
String password = ((SampleModel) validatedObject).password;
// ユーザー名にパスワードを含んでいたら入力チェックエラーとする。
// 入力チェックエラー=falseを返す。
return !(name.contains(password));
}
}
}
@CheckWith内で設定するパラメータを表にしたものが次の表です。
| 名前 | 型 | 説明 |
| value | Class | 入力チェック内容を実装しているインナークラス |
| message | String | 入力チェックエラーと判定したときに出力されるメッセージ |
複数項目に対する入力チェックは、インナークラスで実装します。そのインナークラスの実装ルールを次に示します。
- @CheckWithのvalueに宣言されたインナークラスを必ず作成する
- インナークラスはCheckWithCheck.SimpleCheckインターフェイスを必ず実装する
- public boolean isSatisfied(Object validatedObject, Object value)にチェックロジックを実装する
- ランタイム例外を検出した場合でも、想定されるものであればメソッドないしはインナークラス内で完結する
ではサンプルを稼動させて確認してみましょう。先ほどと同様、http://127.0.0.1:8080/OValSample/oval/execute.action をブラウザで開き、まずは入力禁止文字列をチェックするロジックを設定した名前にaを3つ以上並べた値を入力し、[送信]ボタンを押します。
送信ボタンを押した結果、図6のように@ValidateWithMethodで設定した入力チェックエラーが稼動します。
続いて@CheckWithの稼動です。パスワードに入力した文字列が名前に含まれてはいないかを確認するロジックを実装しましたので、今回は名前にnamepassword、パスワードにpasswordと入力し、それ以外の項目にも値を入れておいて[送信]ボタンを押します。
送信ボタンを押した結果、図8のように@CheckWithで設定した入力チェックエラーが稼動します。
まとめ
今回はOValプラグインの簡単な紹介をしました。既存のValidationよりも記述が減りつつ、機能もさらに拡張されていながらも、従来どおりの実装が可能になっていることがお分かりいただけましたでしょうか。
次回は、Struts 2のActionクラスに対してSpring Frameworkを利用することが可能になるSpringプラグインの紹介をします。




