|
メッセージリソース、ValidatorForm、validation.xmlを利用したエラー処理についてのメモです。
- リソースファイルを作成します。
errors.header=<h2 align="center"><font color="red">エラーですよ</font></h2><ul>
errors.footer=</ul><hr>
errors.prefix=<li>
errors.suffix=</li>
errors.required={0}が入力されていません。
error.generic={0}
error.shitenCode.required=支店コードを入力して下さい。
error.shitenCode.notexist=入力された支店コードは存在しません。
error.shitenName.required=支店名を入力して下さい。
error.areaCode.required=地域コードを入力して下さい。
shitenCode.displayName=支店コード
|
ファイル名は「ApplicationResources.properties」とするのが慣例で、
WEB-INF/classesディレクトリの下に置きます。
サブディレクトリの中でも構いません。
ここでは /WEB-INF/classes/shiten/struts の下に置いたとします。
classesの下なので、当然他のJavaクラスファイルなどと同じディレクトリにすることもできます。
ここで注意が必要なのは、上記のようにメッセージに日本語を使う場合には、
native2asciiなどのツールを使ってファイルをASCII文字コードだけからなるように変換しておく必要がある
、ということです。
-
リソースファイルの位置を、struts-config.xmlの中に書きます。
これはディレクトリ階層を、Javaパッケージ階層風に書きます。
例えば上記のパスの場合、下のようになります。
<message-resources parameter="shiten.struts.ApplicationResources"/>
|
-
Actionクラスのexecuteメソッドで、エラーかどうかをロジカルに判断し、
エラーの場合には次のようなコードを書きます。(Struts 1.2の場合)
public ActionForward execute(
ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
/* ... */
if (result == null) {
/* 該当レコードがなかった */
ActionMessages ms = new ActionMessages();
ActionMessage m = new ActionMessage("data.not.found");
ms.add(ActionMessages.GLOBAL_MESSAGE, m);
saveErrors(request, ms);
return mapping.findForward("retry");
}
/* ... */
}
|
errors.addの最初の引数は、エラーを表示するJSP文書の側で、
エラーメッセージを表示するhtml:errorsタグの位置を複数に分けたい場合などに、
エラーメッセージをグループ分けするために使用する文字列で、
そのようなことをしないこの例では ActionMessages.GLOBAL_MESSAGE を指定しています。
ActionMessageクラスのコンストラクタには、
エラーメッセージを保持するメッセージリソースの名前(キー)を指定します。
このメッセージリソースがプレースホルダー{0}〜{3}を含んでいる場合には、
このコンストラクタの引数の後ろにそれらに置き換わる文字列を指定することができます。
(つまりActionMessageのコンストラクタには(String)から(String,String,String,String)
までの4種類があります)
-
エラーが発生したときにフォワードされるJSP文書には、
html:errorsタグを書いておきます。
するとこの位置にエラーメッセージが表示されます。
<%@ page contentType="text/html;charset=Windows-31J" language="java" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:html locale="true">
<head>
<title>支店コード表のメンテナンス</title>
<html:base/>
</head>
<body bgcolor="white">
<body>
<html:errors/>
<html:form action="/ShitenEditC1" focus="shitenCode">
支店コード:
<html:text property="shitenCode" size="10" maxlength="5"/>
<br>
<html:submit value="検索"/>
<html:reset/>
</table>
</html:form>
<html:img page="/struts-power.gif" alt="Powered by Struts"/>
</body>
</html:html>
|
エラーではなくて処理結果のメッセージを格納したい場合 |
ActionからJSPにメッセージを返すのは、常にエラーメッセージとは限りません。
処理結果を伝えるのもほぼ同様の方法で可能です。
int ocount = loader.getTotalLineCount();
int ecount = loader.getErrorLineCount();
ActionMessages ms = new ActionMessages();
ActionMessage m = new ActionMessage("loader.success",
String.valueOf(ocount), String.valueOf(ecount));
ms.add(ActionMessages.GLOBAL_MESSAGE, m);
saveMessages(request, ms);
|
エラーの場合との唯一の違いは、saveErrors()の代わりにsaveMessages()を使うことです。
そしてエラーではないメッセージの場合、html:errorsタグでは表示されないので、
次のようなタグで表示します。
<html:messages id="msg" message="true">
<bean:write name="msg" ignore="true"/>
</html:messages>
|
エラー処理をAction主導ではなく、フォームBeanの中に書く方が再利用性があります。
ここからが本来のバリデーションということで、
まずはフォームBeanに検証ロジックを持たせる方法です。
-
フォームBeanを
ActionFormではなく、org.apache.struts.validator.ValidatorForm
を継承して作成します。
package shiten.struts;
import org.apache.struts.action.*;
import org.apache.struts.validator.ValidatorForm;
import javax.servlet.http.*;
public class ShitenEditC1Form extends ValidatorForm {
/* ... */
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (shitenCode == null || shitenCode.trim().equals("")) {
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("error.shitenCode.required"));
}
return errors;
}
}
|
継承したクラスには、オーバーライドメソッド validate()を記述します。
このクラスはチェックが正常に終了したら要素を持たないActionErrorsオブジェクトを、
エラーが発生したらその内容を説明するActionErrorオブジェクトを含む
ActionErrorsオブジェクトを返すように書きます。
-
struts-config.xmlのActionマッピングを設定します。
<action-mappings>
<action path="/ShitenEditC1" type="shiten.struts.ShitenEditC1Action"
attribute="ShitenEditC1Form" name="ShitenEditC1Form"
scope="request" validate="true" input="/ShitenEditC1.jsp">
<forward name="retry" path="/ShitenEditC1.jsp"/>
<forward name="success" path="/ShitenEditC2.jsp"/>
</action>
...
|
ValidatorFormを使用してバリデーションを行うには、
validate="true"とします。またtrueにした場合には、input属性の指定が必須になります。
これは、バリデーションに失敗した場合に、
戻されるJSP文書などのURLを、/で始まる、コンテキストルートからの相対パスで指定します。
ValidatorFormとvalidation.xmlでエラー処理を書く場合 |
必須チェック(空文字列は不可)のような、典型的な幾つかのバリデーションについては、
validateメソッドを実装しなくても、
validation.xmlの仕組みを使うことによって、バリデーションを行わせることができます。
まず上のクラスのvalidateメソッドを削ってから、次のようにします。
-
struts-config.xmlでアクションフォームBeanを設定します。
<form-bean name="ShitenEditC1Form" type="shiten.struts.ShitenEditC1Form">
<form-property name="shitenCode" type="java.lang.String" initial="00100" />
</form-bean>
|
-
validation.xmlに検証規則を書きます。
この詳細は設定ファイルのメモの通りです。
<formset>
<form name="ShitenEditC1Form">
<field property="shitenCode" depends="required">
<arg position="0" key="shitenCode.displayName" />
</field>
</form>
</formset>
|
DynaValidatorFormとvalidation.xmlでエラー処理を書く場合 |
各入力フォームに対して1つずつ自作のフォームBeanを開発するのに代わって、
DynaActionFormという、プロパティを動的に指定できるフォームBeanを使うことができるようになり、
とても便利になりました。
そして、DynaActionFormに検証機能を持たせたのがDynaValidatorFormです。
プロパティの定義をstruts-config.xmlのform-bean要素に、
バリデーションの定義をvalidation.xmlに書くことで、
Javaコードを全く書かずにForm Beanを定義することが可能です。
-
struts-config.xmlでアクションフォームBeanを設定します。
<form-bean name="ShitenEditC1Form" dynamic="true"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="shitenCode" type="java.lang.String" initial="00100" />
</form-bean>
|
typeに
"org.apache.struts.validator.DynaValidatorForm"を指定します。
プロパティ設定は普通に自作フォームBeanのときのように行うことができます。
なおActionマッピングの書き方はValidatorFormの場合と同じです。
-
validation.xmlに検証規則を書きます。書き方はValidatorFormの場合と全く同じです。
(first uploaded 2003/10/26 last updated 2007/01/07, URANO398)
|