24. Struts 1.2.x
2006.08.15 株式会社四次元データ 鈴木 圭
- 24.1. ワイルドカード・マッピング
- 24.2. MappingDispatchAction
- 24.3. stopOnFirstError
- 24.4. キャンセル・ハンドラ (DispatchAction#cancelled)
- 24.5. validator の変更
- 24.6. ActionRedirect
- 24.7. DownloadAction
- 24.8. セッション・スコープの ActionMessages
- 24.9. エラーのハイライト
- 24.10. その他の追加/変更
24.6. ActionRedirect
org.apache.struts.action.ActionRedirect クラスはリダイレクトを行うための ActionForward のサブクラスです。ActionRedirect#addParameter メソッドを使用することで、は動的にリクエスト・パラメータを追加することができます。以下に使用例を示します:
public class ActionRedirectSample extends Action { public ActionForward execute(...) { ActionRedirect actionRedirect = new ActionRedirect(mapping.findForward("success")) actionRedirect.addParameter("name", "guest"); actionRedirect.addParameter("message", "hello"); return actionRedirect; } }
この例では "success" という名前でマッピングされている ActionForward を ActionRedirect でラップし、リクエスト・パラメータを追加しています。
Struts 1.1.x から存在した org.apache.struts.action.RedirectingActionForward を使用してリダイレクトを行う場合は、以下のようにリクエストパラメータを含めた URL を作成しなければなりませんでしたが、ActionRedirect では既存の ActionForward を元にすることができることや、リクエスト・パラメータを簡単に追加するためのメソッドを持っていることなど、RedirectingActionForward よりも使いやすいものとなっています。
// RedirectingActionForward で同じような処理を行う例 public class RedirectingActionForwardSample extends Action { public ActionForward execute(...) { return new RedirectingActionForward( "SaveMessage.do?name=guest&message=hello"); } }
24.7. DownloadAction
org.apache.struts.actions.DownloadAction はファイルのダウンロードを簡単に実現するための抽象クラスです。派生クラスは DownloadAction#getStream メソッドを実装します:
protected abstract DownloadAction.StreamInfo getStreamInfo( org.apache.struts.action.ActionMapping mapping, org.apache.struts.action.ActionForm form, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.lang.Exception
DownloadAction#getStream メソッドはダウンロードされるデータに関する情報を持つ DownloadAction.StreamInfo (DownloadAction の内部インタフェース) を返します。:
DownloadAction.StreamInfo インタフェースは以下のメソッドを持ちます:
java.lang.String getContentType() java.io.InputStream getInputStream() throws java.io.IOException
getContentType メソッドは "text/plain" や "image/jpeg" など、ダウンロードするデータのコンテンツ・タイプを返します。getInputStream メソッドはダウンロードするデータの InputStream を返します。
DownloadAction は DownloadAction.StreamInfo のデフォルトの実装として、ディスクに保存されたファイルのダウンロードのための DownloadAction.FileStreamInfo クラスと Web アプリケーションのリソースをダウンロードするための DownloadAction.ResourceStreamInfo クラスを提供しています。どちらのクラスもコンストラクタで必要な情報を渡します。
DownloadAction.FileStreamInfo のコンストラクタにはコンテンツ・タイプと ダウンロードするための File オブジェクトを渡します:
public DownloadAction.FileStreamInfo(java.lang.String contentType, java.io.File file)
DownloadAction.ResourceStreamInfo のコンストラクタにはコンテンツ・タイプと ServletContext およびダウンロードするためのリソースのパスを渡します:
public DownloadAction.ResourceStreamInfo(java.lang.String contentType, javax.servlet.ServletContext context, java.lang.String path)
以下に DownloadAction.ResourceStreamInfo を用いて "images/sample.png" をダウンロードするための DownloadAction クラスの実装例を示します:
public class DownloadHelloAction extends DownloadAction { @Override protected DownloadAction.StreamInfo getStreamInfo( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { return new DownloadAction.ResourceStreamInfo( "image/png", servlet.getServletContext(), "images/sample.png"); } }
24.8. セッション・スコープの ActionMessages
Struts 1.2 から追加された Action#saveMessages(HttpSession session, ActionMessages messages) メソッドを使用すると、第 1 引数に指定する HttpSession に ActionMessages を保存できます。
24.9. エラーのハイライト
validation によって検証に失敗したフィールドをハイライト表示するために、html タグライブラリのいくつかの要素に errorKey, errorStyle, errorStyleClass, errorStyleId 属性を指定できるようになりました。
errorKey | エラーメッセージを持つ ActionMessages を登録するときの名前を指定します。この属性を省略した場合は Globals.ERROR_KEY が使用されます。(詳しくは下記「errorKey の使い方」を参照) |
errorStyle | 検証に失敗したフィールドに付加される style 属性の値を指定します。例えば「<html:text errorStyle="background-color:red" ... />」のように指定すると、検証に失敗した場合にだけ「style="background-color"」属性が付加されます。 |
errorStyleClass | 検証に失敗したフィールドに付加する class 属性の名前を指定します。例えば「<html:text errorStyleClass="errorField" ... >」のように指定すると、検証に失敗した場合にだけ「style="errorField"」属性が付加されます。 |
errorStyleId | 検証に失敗したフィールドに付加する id 属性の名前を指定します。例えば、「>html:text errorStyleId="errorId" ... >」のように指定すると、検証に失敗した場合にだけ「id="errorId"」属性が付加されます。 |
これらの属性を指定することができる html タグライブラリの要素を以下に示します:
- checkbox
- file
- multibox
- password
- radio
- select
- text
- textarea
24.9.1 errorKey の使い方
通常、検証に失敗して作成された ActionErrors は Globals.ERROR_KEY をキーに request などに設定されます。そして errorStyle などは errorKey で指定された値 (デフォルトでは Globals.ERROR_KEY) をキーとして取得できる ActionErrors に自身のフィールド名で ActionMessage が登録されている場合に、検証に失敗したと判断し、指定されたスタイルを適用します。そのため、以下に示す miscellaneous.jsp のように一つのページに複数のフォームがあり、異なるフォームに同名のフィールド ("email") が存在した場合に、片方のフィールドの検証に失敗したときに、同名のフィールド両方にエラー用のスタイルが適用されてしまう、という問題が発生してしまいます:
--- miscellaneous.jsp --- <html:html> <head> ... </head> <body> メンバー登録 <html:form action="/registerMember"> 名前: <html:text errorStyle="background-color:red" property="name" /> メールアドレス: <html:text errorStyle="background-color:red" property="email" /> </html:form> メーリングリスト登録 <html:form action="/registerMailingList"> メールアドレス: <html:text errorStyle="background-color:red" property="email" /> </html:form> </body> </html:html>
このような問題を避けるためにあるのが errorKey です。errorKey は ActionErrors が登録されているキーを指定するための属性で、一つのページに複数のフォームがある場合でも、それぞれにユニークな値を errorKey に指定しておけば、上記のような問題を避けることができます。また、errorKey は ActionErrors が登録されているキーを示すだけなので、実際の errorKey で指定した値をキーとして ActionErrors が (request などに) 登録されるように処理を行わなければなりません。
- JSP の <html:text> などで errorKey を指定する。
- ActionErrors が errorKey で指定した値をキーとして登録されるようにする。
まず、先ほどの miscellaneous.jsp に errorKey の指定を加えると以下のようになります:
--- miscellaneous.jsp / errorKey 使用版 --- <html:html> <head> ... </head> <body> メンバー登録 <html:form action="/registerMember"> 名前: <html:text errorKey="menberKey" errorStyle="background-color:red" property="name" /> メールアドレス: <html:text errorKey="memberKey" errorStyle="background-color:red" property="email" /> </html:form> メーリングリスト登録 <html:form action="/registerMailingList"> メールアドレス: <html:text errorKey="mlKey" errorStyle="background-color:red" property="email" /> </html:form> </body> </html:html>
ここでは、メンバー登録フォームのフィールドには "memberKey" という errorKey を指定し、メーリングリスト登録フォームのフィールドには "mlKey" という errorKey を指定しています。
次に ActionErrors が errorKey に指定した値をキーとして登録されるようにしなければなりません。ここで一つ問題があり、ValidatorForm#validator が返す ActionErrors は Struts によって Globals.ERROR_KEY をキーに request に登録されてしまいます。つまり通常どおりに ValidatorForm#validate をオーバーライドし、ActionErrors を返すだけでは不十分です。そこで、ValidatorForm#validate をオーバーライドするときは、以下のように request.setAttribute で errorKey に指定した値をキーに ActionErrors を登録します:
public class RegisterMemberForm extends ValidatorForm { private String name; private String email; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if(name == null || name.equals("")) { errors.add("name", new ActionMessage("required")); } if(value2 == null || value2.equals("")) { errors.add("email", new ActionMessage("required")); } // 作成した ActionErrors は errorKey に指定した値をキーに // request に登録する. request.setAttribute("memberKey", errors); return errors; } }
こうすることで、ActionErrors が "memberKey" (errorKey に指定した値) をキーに request に登録されます。
また、別の方法として ValidatorForm#validate を継承するのではなく、Action の execute メソッド内部で validation を行い、作成した ActionErrors を request に登録する方法もあります。
24.10. その他の追加/変更
24.10.1 forward によるモジュールの変更
forward 要素を持ついくつかのタグに module 要素を指定できるようになりました。これにより、org.apache.struts.actions.SwitchAction を使用しなくてもモジュールの変更を行うことができます。
24.10.2 ModuleConfigVarifier
org.apache.struts.plugins.ModuleConfigVerifier はモジュールの設定 (org.apache.struts.config.ModuleConfig に設定されている情報) の検証を行うためのプラグインです。このクラスを継承して独自の検証を加えることもできます。
24.10.3 DigestingPlugIn
Commons Digester を用いてオブジェクトを作成する org.apache.struts.plugins.DigestingPlugIn が追加されました。DigestingPlugIn によって作成されたオブジェクトはアプリケーション・コンテキストに保存されます。
24.10.4 追加/削除/非推奨となったクラスなど
Action クラスにあった static フィールドが Globals クラスにまとめられたことや、ActionMessages 関係での変更では ActionError が非推奨になるなど、いくらかの整理が行われました:
- [削除] org.apache.struts.Action の static フィールド
=> 代わりに org.apache.struts.Globals を使用する。 - [削除] Action#perform()
=> 代わりに Action#execute() を使用する。 - [非推奨] ActionError (ActionError's' ではない)
=> 代わりに ActionMessage を使用する。 - [追加] Action クラスに getErrors(), getMessages(), addErrors(), addMessages() メソッドが追加された。
- [非推奨] ActionErrors.GLOBAL_ERROR
=> 代わりに ActionMessages.GLOBAL_MESSAGE を使用する。 - [追加] org.apache.struts.util.ModuleUtils