クライアント側妥当性検査の実装

Jennifer Ball

課題

大部分の Web アプリケーションには、ユーザーが値を入力するか、一覧から項目を選択するためのフォーム要素が含まれています。Web アプリケーションはこれらの値や選択内容の妥当性を検査し、Web アプリケーションが実行されているシステムを不正に制御しようとする者によってしばしば使用される不正なデータから、そのビジネスオブジェクトを防御する必要があります。

Web アプリケーションに妥当性検査コードを含める方法はいくつかあります。これらの妥当性検査の方法には、サーバー側で妥当性検査を行う方法もあれば、クライアント側、あるいはその両方で行う方法もあります。サーバー側妥当性検査とクライアント側妥当性検査にはそれぞれ長短があります。

クライアントで妥当性検査を行うと、ネットワークトラフィックが減り、サーバーに対する負荷が軽減されます。しばしば、この結果として、応答時間が短くなり、最終的にはユーザーが快適な操作感が得られます。しかしながら、妥当性検査を行う必要があるすべてのクライアントが、クライアント側スクリプトをサポートしているわけではありません。さらに、サポートしているスクリプト言語がクライアントによって異なることがあります。このため、開発者は、アプリケーションにクライアント側妥当性検査に対するサポートを含めるかどうかに関係なく、最低限、サーバー側妥当性検査を提供する必要があります。

クライアント側妥当性検査と異なり、サーバー側妥当性検査には、サーバーへのラウンドトリップが余分に必要であり、もっとも簡単な妥当性検査でも応答時間が悪くなります。しかしながら、サーバー側でだけ妥当性検査を行えば、増加するクライアントのサポートについて心配する必要はなくなります。

クライアント側とサーバー側両方の妥当性検査を提供することにした場合は、2 つの冗長コードの保守に煩わされることになります。

開発者は、サーバー側妥当性検査コードに適用されるのと同じ一群の規則でクライアント側スクリプトを生成することによって、クライアント側とサーバー側妥当性検査の利点を最大限活かしながら、その欠点を最低限に抑えることができます。実際、入力の妥当性を判定するために、クライアント側スクリプトがサーバー上の情報にアクセスする必要がある状況では、この対処法が欠かせないことがあります。

対処法

JavaServer[tm] Faces の多数の強力な機能の 1 つにその妥当性検査モデルがあります。このモデルは、アプリケーションに基本的なサーバー側妥当性検査を簡単に含められるようにするばかりでなく、独自の対処法を実装するための柔軟なプログラミングモデルを提供します。

JavaServer Faces にはまだ、クライアント側妥当性検査のサポートはありません。ただし、JavaServer Faces コンポーネント描画モデルを使用し、さまざまなクライアントを対象にしたクライアント側妥当性検査コードを生成する機能を持つレンダリングを作成することができます。

異なるクライアントで動作可能なアプリケーションには大きなメリットになる可能性がある一方、この方法では、サーバー側妥当性検査とクライアント側妥当性検査の 2 つの冗長コードの保守が必要になります。

HTML でのみ描画されるアプリケーションの場合、この解決策は、Struts Validator を使用する一方で、その他の機能は JavaServer Faces テクノロジに含まれる機能を使用する方法です。Struts Validator には、標準で多くの妥当性検査が含まれているばかりでなく、それらはサーバー側とクライアント側両方の妥当性検査を行うことができます。Struts Validator ではまた、妥当性検査の対応するクライアント側 JavaScript[tm] を含む 一元化された validator-rules.xml ファイルに追加することによって、プラグインとして独自の妥当性検査を組み込むことができます。一元化された規則ファイルによって、クライアント側とサーバー側コードの保守も容易になります。

これまでの情報を踏まえた上で、推奨できることは次のとおりです。

以降の項目で、JavaServer Faces テクノロジを単独で使用するか、Struts と併用するかしてクライアント側妥当性検査を行う方法を詳しく説明します。

JavaServer[tm] Faces ページへのクライアント側スクリプトの追加

JavaServer Faces テクノロジには、HTML クライアントに描画可能なデフォルトのコンポーネントが用意されています。このことは、HTML "onsubmit" 属性を JavaServer Faces HTML フォームコンポーネントに関連付けられることを意味します。この JavaServer Faces 属性名は大文字と小文字が区別され、属性名にすべて小文字を使用する必要があることに注意してください。

以下は、JavaServer Faces ページに含まれる JavaScript タグ例です。



<script language="JavaScript">
function client_validation() {
if (document.forms[0].elements["validatorForm:color"].value =="red")
return true;
} else if (document.forms[0].elements["validatorForm:color"].value =="green") {
return true;
} else if (document.forms[0].elements["validatorForm:color"].value =="blue") {
return true;
} else {
alert("Enter a red, green, or blue for the color.");
return false;
}
}
</script>


<h:form id="validatorForm" onsubmit="return client_validation();">
...
<p>Enter a color (red,green, or blue):</p>
<h:inputText id="color" value="#{ValidatorBean.color}"/>
<p>
<h:commandButton id="submit" action="success" value="Submit" />
</p>
</h:form>


このフォームは、JavaScript を使用した妥当性検査を示しています。JavaScript でチェックされるフォーム要素の id は、[form name]:[form element id] の形式で指定することに注意してください。この例の場合は、名前として validatorForm:color を使用して色入力要素を参照することになります。フォーム要素の id にコロンが 1 つ使用されているため、window.document.validatorForm.validatorForm:color.value == "red") などの方法を使って JavaScript からフォーム要素にアクセスすることはできません。

JavaScript コードがページにハードコーディングされていることに注目してください。この方法は、JavaScript コードが 1 つまたは少数のページでしか使用されず、サーバーからのデータまたは処理を必要としない場合に受け入れられる方法です。

スクリプトが複数のページで使用される場合は、スクリプトを別のページ (clientValidation.js など) に置いて、特別なスクリプトタグを使ってページに取り込んだ方が合理的です。

<script language="Javascript" type="text/javascript" src="clientValidation.js"/>

ただし、この対処法は、スクリプトがサーバーからの情報を必要とする場合の問題を解決するわけではありません。これら、またほかの多くの理由から、しばしば、クライアント側スクリプトを生成した方が良いことがあります。以下では、この点について説明します。

カスタムレンダリングによる JavaScript[tm] の生成

クライアント側スクリプトが、その機能を実行するためにサーバーからのデータを必要とする場合は、サーバーでそのデータを生成する一方で、スクリプトにそのデータを取り込む必要があります。また、スクリプトを生成することによって、手動でほかのページをコピーする必要もなくなります。

スクリプトを生成するもう 1 つの理由は、さまざまなクライアント (JavaScript をサポートしていないものも含めて) がアプリケーションを実行できるようにする場合です。JavaServer Faces テクノロジには、機能豊富なコンポーネント描画モデルがあり、このモデルを使用し、さまざまな方法でさまざまなクライアントへのコンポーネントの描画に使用できるカスタムレンダリングを作成できます。

コンポーネントの機能は、コンポーネントクラスそのものによってカプセル化されます。たとえば標準の UISelectOne コンポーネントでは、一組の値のうちの 1 つを選択できます。レンダリングでは、このコンポーネントでのページでの表示方法を定義できます。UISelectOne コンポーネントは、適切なレンダリングを適用することによって、一組のラジオボタン、あるいは 1 つのメニューかリストボックスなどとして描画できます。ページ作成者は、ページ上で適切なタグを使用することによって、コンポーネントとレンダリングのこの組み合わせを選択します。標準のタグの selectOneRadio は、一組のラジオボタンを描画する、UISelectOne コンポーネントと Radio レンダリングの組み合わせを表します。

カスタムレンダリングを使用してクライアント側ページを描画することもできます。この場合、サーバー側でスクリプトを生成できるため、スクリプトがサーバー側データにアクセスできるようになります。また、このことに加えて、レンダリングは、特定のクライアントに適したスクリプトを描画するものを個別に作成できるという事実があります。このため、開発者は、アプリケーションにクライアント側スクリプトを組み込む、かなり柔軟で移植性の高い手段を手にすることになります。

クライアント側スクリプトの場合、カスタムレンダリングに加えてカスタムコンポーネントを作成する必要はありません。代わりに標準のコンポーネントを利用できます。コンポーネントに対してカスタムレンダリングを作成するために行う必要がある作業は、次のとおりです。

カスタムレンダリングを使ってスクリプトを描画する方法を具体例として、前項の例を取り上げてみましょう。今回は、ページにスクリプトをハードコーディングするのではなく、スクリプトを生成するカスタムレンダリングを作成します。

コンポーネントの選択

カスタムレンダリングからカスタムタグを描画するには、レンダリングとコンポーネント (標準またはカスタムコンポーネントのどちらでも可) を対にする必要があります。単にフォーム内に script タグをレンダリングするだけのこの例では、単純コンポーネントの UIOutput で十分です。個々のフォームコンポーネントにクライアント側スクリプトを追加する場合は、そのコンポーネントをカスタムコンポーネント (このカスタムコンポーネント用にカスタムレンダリングを作成できる) にするか、ページ上の対応するコンポーネントタグにそのスクリプトを追加するようページの作成者に依頼する必要があります。たとえばページの作成者は、なんらかの JavaScript を持つ (あるいは JavaServer Faces EL 使ってスクリプトを参照する) onselect 属性 を、チェックボックスコンポーネントを表すタグに追加することができます。

レンダリングクラスの作成

一般に、レンダリングクラスには、マークアップを生成するエンコーディングメソッドが含まれます。ColorRenderer から ColorRenderer メソッドを抜粋したものを、次に示します。JavaServer Faces 実装は、レンダリングを行うコンポーネントで encodeEnd メソッドを呼び出し、この例では、このコンポーネントとして、 UIOutput コンポーネントをこのレンダリングに関連付けます。encodeEnd メソッドで示されているように、このレンダリングは、ページにハードコーディングしたスクリプトと同じことを行うスクリプトを生成します (上記の「JavaServer Faces ページへのクライアント側スクリプトの追加」を参照)。

public void encodeEnd(FacesContext context, UIComponent component)
throws IOException {

if ((context == null) || (component == null)) {
throw new NullPointerException();
}
UIOutput script = (UIOutput) component;
UIInput currentColor = (UIInput) component.findComponent("color");
ResponseWriter writer = context.getResponseWriter();
StringBuffer sb = null;

System.out.println("currentColor =" + currentColor);
if (currentColor == null)
return;
sb = new StringBuffer("function client_validation() {\n");
sb.append("if (document.forms[0]['");
sb.append(currentColor.getClientId(context));
sb.append("'].value=='red' ) {").append("\n");
sb.append("return true;");
sb.append("\n} else if (document.forms[0]['");
sb.append(currentColor.getClientId(context));
sb.append("'].value=='green' ) {").append("\n");
sb.append("return true;");
sb.append("\n} else if (document.forms[0]['");
sb.append(currentColor.getClientId(context));
sb.append("'].value=='blue' ) {").append("\n");
sb.append("return true;");
sb.append("\n } else {\n");
sb.append("alert('Enter red, green, or blue for the color.');");

sb.append("\nreturn false;\n");
sb.append("} \n }");
sb.append("\n");
if (writer != null) {
writer.startElement("script", script);
writer.writeAttribute("language", "JavaScript", "script");
writer.write(sb.toString());
writer.endElement("script");
}
}

カスタムレンダリングの登録

レンダリングを作成したら、アプリケーション構成ファイルを使用してレンダリングキットにそのレンダリングを登録する必要があります。レンダリングキットは、特定のクライアントに適したマークアップを出力する機能を持つレンダリングをまとめたものです。

前項で説明した ColorRenderer を登録する render-kit 要素を、次に示します。component-family 要素は、このレンダリングが描画可能なコンポーネントを示すコンポーネント型で、renderer-type 要素はレンダリングの種類です。renderer-class 要素は、クラスの実際の名前です。

<render-kit>
<renderer>
<component-family>javax.faces.component.UIOutput</component-family>
<renderer-type>Color</renderer-type>
<renderer-class>ColorRenderer</renderer-class>
</renderer>
</render-kit>

前述したように、アプリケーションは、それぞれ特定のクライアントに適したスクリプトをレンダリング可能な複数のレンダリングを利用できます。複数のレンダリングを作成した場合は、必ず、アプリケーション構成リソースファイルに対応するレンダリング要素タグを追加してください。

次項では、タグハンドラクラスがこのコンポーネント型とレンダリングの種類に基づいて、JavaServer Faces 実装にコンポーネントをレンダリングする方法を指示する方法を説明します。

タグハンドラクラスの作成

タグハンドラが行うことの 1 つは、タグに関連付けられているコンポーネントの型を読み出すことです。また、JavaServer Faces 実装にレンダリングの種類 (レンダリングがある場合) を返して、タグが処理されたときにコンポーネントのエンコーディングが行えるようにします。

この例でこれらの働きを持つ、ScriptTag のメソッドを抜粋したものを次に示します。

public String getComponentType() {
return ("javax.faces.component.UIOutput");
}

public String getRendererType() {
return ("Color");
}

これらのメソッドの返すコンポーネント型とレンダリングの種類が、アプリケーション構成ファイル内の render-kit 要素で設定されている対応する型または種類に一致している必要があることに注意してください。タグハンドラクラスの作成方法に関する詳細は、J2EE[tm] 1.4 チュートリアルを参照してください。

アプリケーションが複数のレンダリング (それぞれ、特定のクライアントに適したスクリプトをレンダリングする) を使用する場合は、タグハンドラクラスの getRendererType メソッドに次のようなコードを追加する必要があります。

String agent = (String) getFacesContext().getExternalContext().getRequestHeaderMap().get("User-Agent");
if ((agent != null) && (agent.contains("Mozilla")) {
.... this is a Mozilla client, so return the type of the
renderer that handles this client ...

}...

このメソッドは、アプリケーションを実行しているクライアントを特定し、適切なレンダリングの種類を返します。前節で説明しているように、アプリケーション構成リソースファイルに対応するレンダリングを登録する必要もあります。

最後のステップは、カスタムタグを定義する TLD ファイルの作成です。以下は、ここでの例の TLD ファイルの抜粋です。

<taglib>
...
<display-name>customTags</display-name>
<tag>
<name>script</name>
<tag-class>ScriptTag</tag-class>
<body-content>empty</body-content>
...
</tag>
</taglib>

最後に、次に示すような TLD ファイルおよびカスタムタグに関する taglib 指示をページに含めます。

<%@ taglib prefix="customTags" uri="WEB-INF/customTags.tld" %>
...
<h:form id="validatorForm" onsubmit="return client_validation();">
<p>Enter a color (red, green, or blue):</p>
<h:inputText id="color" >
...
<customTags:script/>
</h:form>

クライアント側妥当性検査を提供するかどうかに関係なく、すでに説明したようにサーバー側でもデータを妥当性検査するのは適切なことです。次節では、この例にサーバー側妥当性検査を追加する方法を説明します。

サーバー側妥当性検査の追加

JavaServer Faces テクノロジに標準で付属している妥当性検査にニーズに合うものがある場合は、その妥当性検査を使用してください。その場合、開発者が用意する必要があるのは、カスタムレンダリングを作成することによる、対応するクライアント側スクリプトだけです。

独自のサーバー側妥当性検査コードを用意する必要がある場合は、Java BluePrints Solutions Catalog の「サーバー側妥当性検査」エントリを参照してください。独自のサーバー側妥当性検査を行う多数の方法を紹介しています。アプリケーションでのクライアント側妥当性検査とともにサーバー側妥当性検査を行う場合は、これらの方法のどれでも利用できます。

ここでの例では、カスタム妥当性検査クラスがあるものと仮定します。ページ作成者は、標準の validator タグを使って、このクラスを参照します。このドキュメントの例では、この対処法がもっとも合理的です。なぜなら、ページ作成者が妥当性検査パラメータを設定する必要がなく、このため、開発者が、ページ上で妥当性検査を表すカスタムタグを提供する必要はありません。

以下は、ColorValidator からの validate メソッドの抜粋です。

public void validate(FacesContext context, UIComponent component, 
Object toValidate) {
String value = null;
if ((context == null) || (component == null)) {
throw new NullPointerException();
}

if (!(component instanceof UIInput)) {
return;
}

if ( null == toValidate) {
return;
}

value = toValidate.toString();
if (value.equals("red") || value.equals("green") ||
value.equals("blue")) {
return;
} else {
System.out.println("value "+value);
FacesMessage errMsg = MessageFactory.getMessage(context,
COLOR_INVALID_MESSAGE_ID);
throw new ValidatorException(errMsg);
}
}
}

基本的には、カスタム妥当性検査の妥当性検査ロジックはレンダリングクラスのロジックと同じであることに注目してください。ただし、このことは、2 つの冗長コードを保守する必要があることを意味します。レンダリングエンコーディングメソッド内の String に手動でスクリプトを入力して妥当性検査に Java コードを生成する必要があるため、保守しやすいようにクライアント側妥当性検査とサーバー側妥当性検査を適切な位置に作成するのは難しくなります。

役立つかどうかはケースによって異なりますが、メソッドに渡すパラメータを使用し、レンダリングの encodeEnd からカスタム妥当性検査にアクセスできます。

public void encodeEnd(FacesContext context, UIComponent component)
throws IOException {
...
UIInput inputComponent = (UIInput) component;
Validator[] = inputComponent.getValidators();
// 続いて、探している妥当性検査を配列から取得
...
}

この場合、レンダリングの encodeEnd メソッドからアクセスしたあとで、サーバー側妥当性検査コードにある妥当性検査規則を使用するクライアント側スクリプトを生成することができます。レンダリングが妥当性検査を認識することができ、かつ妥当性検査から行う検査を特定できれば、レンダリングは適切な Java スクリプトを生成できます。この目的でレンダリングがサーバー側妥当性検査規則にアクセスするには、それら規則は、バッキング Bean メソッドではなく、レンダリングの認識するカスタム妥当性検査クラスによって定義されている必要があります。レンダリングがバッキング Bean メソッドが実施する妥当性検査規則を特定することはできません。

もう 1 つの優れた対処法としては、クライアント側およびサーバー側の妥当性検査コードの動作を決定する、妥当性検査規則集を定義した外部ファイルを用意する方法があります。Struts Validator には、このことを可能にするクライアント側妥当性検査手段が用意されています。struts-faces 統合ライブラリを利用することによって、JavaServer Faces アプリケーションで Struts Validator を利用できます。

JavaServer Faces アプリケーションでの Struts Validator の利用

すでに説明したように、標準の JavaServer Faces コンポーネント用のレンダリングには、クライアント側妥当性検査のサポートはありません。クライアント側妥当性検査をアプリケーションに組み込むには、前節で説明したように独自の対処コードを作成するか、JavaServer Faces アプリケーションで利用できるクライアント側妥当性検査のサポートを提供するライブラリを利用する必要があります。

Struts-Faces 統合ライブラリは、既存の Struts アプリケーションに JavaServer Faces 機能を組み込むために使用します。 また、このライブラリを使用して、Struts Validator などの Struts 機能を JavaServer Faces アプリケーションに組み込むこともできます。Struts Validator には、複数のクライアントでテスト済みの JavaScript コードが付属する、一群の基本的な妥当性検査があります。次の表は、それらの妥当性検査の一覧です。

  1. Struts 標準妥当性検査
妥当性検査 用途
required ユーザーが値を入力したかどうかを検査
mask mask 属性に指定された正規表現に値が一致するかどうかを検査
range 値が 2 つの値の範囲内かどうかを検査
maxLength
フィールドの長さが、max 属性に指定された値以下かどうかを検査
minLength フィールドの長さが、min 属性に指定された値以上かどうかを検査
byte、short、integer、long, float、double 値がこれのら基本型のいずれかに変換可能かどうかを検査
date 値が有効な日付で、オプションのパターンに準拠しているかどうかを検査
creditCard 値が有効なクレジットカード番号かどうかを検査
email 値が有効な電子メールアドレスかどうかを検査

「サーバー側妥当性検査」の項目をすでに読まれている場合は、Struts には、JavaServer Faces テクノロジより多くの標準妥当性検査があることに気付かれたことでしょう。しかしながら、JavaServer Faces 妥当性検査モデルは自由度が高く、拡張性があるため、JavaServer Faces の標準妥当性検査セットは、近い将来、JavaServer Faces の実装、妥当性検査、コンポーネントの提供者によって充実したものになることがほぼ確実です。

JavaServer Faces アプリケーションですでに標準の JavaServer Faces 妥当性検査を使用していて、その妥当性検査と連携するクライアント側妥当性検査を追加する場合は、カスタムレンダリングによる JavaScript の生成で説明しているように、カスタムレンダリングを作成できます。しかしながら、標準のサーバ側妥当性検査コードが参照実装によって提供されるとしても、アプリケーションに JavaScript を追加した場合、2 つの冗長コードという問題は残ります。

この問題には、Struts Validator を使用して JavaServer Faces アプリケーションから Struts 妥当性検査にアクセスできるようにすることで対処できます。この方法を用いることによって、同じアプリケーション内で潜在的により強力なクライアント側妥当性検査フレームワークを利用しながら、数多くある、JavaServer Faces テクノロジを使用することメリットを享受することができます。

JavaServer Faces アプリケーションへの Struts Validator の追加

JavaServer Faces アプリケーションへの Struts Validator の組み込みは、いくつかの段階に分かれます。

  1. Struts および Struts-Faces 統合ライブラリをダウンロードします。
  2. JavaServer Faces アプリケーションの WEB-INF/lib ディレクトリに次の JAR ファイルを追加します。 struts.jar, commons-validator.jar, commons-lang.jar, and jakarta-oro.jar, struts-faces.jar
  3. 配備記述子 (web.xml) に Struts サーブレットを宣言します。
    <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>
    org.apache.struts.action.ActionServlet
    </servlet-class>
    <init-param>
    <param-name>config</param-name>
    <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
    </servlet>
  4. 次に示すように Struts サーブレットへのマッピングを追加します。 必ず、FacesServlet へのマッピングに使用するのと同じ種類のマッピング (拡張子または接頭辞) を使用してください。
  5. 	<servlet-mapping>
      <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
    </servlet-mapping>
  6. アプリケーションで使用するすべての Struts TLD を宣言します。 struts-faces TLD を宣言する必要はありません。
  7. Struts プロジェクトに付属している validator-rules.xml ファイルを、アプリケーションの WEB-INF ディレクトリに追加します。このファイルはサーバー側妥当性検査を宣言し、アプリケーションで使用する対応するクライアント側 JavaScript コードを定義します。
  8. ページに struts-faces 統合ライブラリをインポートします。

    <%@ taglib prefix="s" uri="http://struts.apache.org/struts/tags-faces" %>

  9. ページ上のフォームタグの外のどこか適当な位置に struts-faces 統合ライブラリの javascript タグを追加します。

    <s:javascript formName="myForm" />

  10. ページ上の h:form タグを、struts-faces 統合ライブラリにある s:form タグに置き換えます。必ず、この form タグに ID を指定し、javascript タグの formName 属性と同じにしてください。
  11. JavaScript validate MyForm (this) を呼び出す onsubmit 属性を form タグに追加します。MyForm は、 formName 属性およびフォームの ID と同じです。
  12. <s:form id="myForm" onsubmit="return validateMyForm(this);">

  13. validator-rules.xml に含まれている妥当性検査ルーチンの、アプリケーションでの適用方法を定義した validator.xml という XML ファイルを作成します。たとえばログインフォームが含まれたページがあり、入力の長さを username フィールドの値に制限する (JavaServer Faces 標準の ValidateLength 妥当性検査の働きに似ている) 場合は、Struts の minlength および maxlength を適用できます。以下は、入力の長さを 3 文字以上、16 文字以下に制限している例です。arg0arg1、および arg2 はそれぞれ、特定の種類の妥当性検査で問題が起きた場合に表示するメッセージの参照です。

    <formset>
    <form name="logonForm">
    <field property="username"
    depends="minlength,maxlength">
    <arg0 key="prompt.username"/>
    <arg1 key="${var:minlength}" name="minlength"
    resource="false"/>
    <arg2 key="${var:maxlength}" name="maxlength"
    resource="false"/>
    <var>
    <var-name>maxlength</var-name>
    <var-value>16</var-value>
    </var>
    <var>
    <var-name>minlength</var-name>
    <var-value>3</var-value>
    </var>
    </field>
    ...
    </formset>
  14. 妥当性検査が必要なフォームに対応する ActionForm bean を作成します。このクラスには、フォームの UI コンポーネントに対応するプロパティーが含まれます。 詳細は、Struts のマニュアルを参照してください。
  15. 要求を処理するための Action クラスを作成します。 同じく詳細は、Struts のマニュアルを参照してください。
  16. struts-config.xml ファイルを取り込みます。このファイルには、妥当性検査メッセージのリソースバンドルや妥当性検査構成ファイル、アクションマッピング、妥当性検査をする必要があるフィールドを含むフォームに対するすべてのフォーム Bean の指定が含まれます。 以下は、それぞれの例です。
  	<form-beans>
<form-bean name="validatorForm"
type="com.sun.j2ee.blueprints.catalog.validator.LoginForm">
</form-bean>
</form-beans>
<action-mappings>
<action path="/logon"
type="com.sun.j2ee.blueprints.catalog.validator.LoginAction"
name="validatorForm"
scope="request"
input="validator"/>
</action-mappings>
<message-resources
parameter="com.sun.j2ee.bleuprints.catalog.validator.ApplicationMessages"/>

見ると分かるように、標準の Struts 妥当性検査を使用するには、JavaServer Faces 標準のサーバー側妥当性検査を使用するよりも、ずっと多くの作業が必要です。このため、JavaServer Faces 標準の妥当性検査にニーズに合うものがある場合、クライアント側妥当性検査を行わないのであれば、その妥当性検査を使用することを推奨します。

しかしながら、Struts Validator には、標準で、それぞれにクライアント側妥当性検査コードが組み込まれたさらに多くの妥当性検査が用意されています。このため、次のような場合は、Struts Validator の利用を検討することを推奨します。

HTML 以外のクライアントにクライアント側妥当性検査を行う必要がある場合は、そのクライアントに適したスクリプトをレンダリングするカスタムレンダリングが必要なため、JavaServer Faces 妥当性検査を使用する必要があります。

Struts Validator を利用したカスタム妥当性検査の実装

Struts Validator は、JavaServer Faces アプリケーションへのカスタム妥当性検査の実装にも利用できます。JavaServer Faces ページへのクライアント側スクリプトの追加で紹介したサンプル妥当性検査コードは、標準の Struts 妥当性検査では実行できません。この例の場合、JavaServer Faces 妥当性検査モデルまたは Struts Validator のどちらを使用するにしても、カスタム妥当性検査を実装する必要があります。このアプリケーションが HTML クライアントでのみ実行される場合は、Struts を利用できます。この場合は、カスタム妥当性検査を実装するための作業が少なくて済み、規則ファイルが一元化されて、妥当性検査コードの保守が容易になるため、対処法としてあるいは優れているといえます。

カスタム妥当性検査を作成、使用するには、次のことを行う必要があります。

  1. validation.xml ファイルでの妥当性検査規則の定義
  2. サーバー側妥当性検査を扱うメソッドの実装
  3. 新しい妥当性検査を表す validator 要素で、validator-rules.xml を更新。この新しい要素は、クライアント側 JavaScript コードも定義します。

このカスタム妥当性検査の作成は、このエントリでカバーすべき範囲を超えているため、読者の課題として残すことにします。 大切なことは、妥当性検査を行う規則を、アプリケーションに固有の、一元化された妥当性検査ファイルで定義するということです。このファイル内の規則には、サーバー側およびクライアント側両方の妥当性検査コードがアクセスするため、規則を変更すると、その両方の動作が変更されます。

このドキュメントで紹介した妥当性検査コードは、より汎用的にして、ColorValidator や ColorRenderer のように単に入力が文字列 "red"、"green"、"blue" のどれかに一致しているかどうかを検査するのではなく、任意の一群の文字列値と比較できるようにすることができます。 比較する文字列は、validation.xml で定義します。 当然、このことは、クライアント側とサーバー側コードの同期が容易になることを意味します。

独自の妥当性検査を作成したら、Struts 標準妥当性検査と同じ validator-rules.xml ファイルで対応するクライアント側 JavaScript を宣言、定義します。

Struts を使ったカスタム妥当性検査の作成については、『Struts Validator Guide』の「Pluggable Validators」の項目を参照してください。

Struts Validator を使ってカスタム妥当性検査を作成することには、多くの利点があります。妥当性検査コードの動作とは別に妥当性検査規則を定義することによって、妥当性検査コードの保守が容易になります。また、アプリケーションコードとの結合が緩やかになり、プラグイン化しやすくなります。

参考資料

この項目に関する詳細は、次の資料を参照してください。


© Sun Microsystems 2004. All of the material in The Java BluePrints Solutions Catalog is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.