Strutsユーザガイド
クイックリンク
ホーム
目次
はじめに
モデル コンポーネント
ビュー コンポーネント
コントローラ コンポーネント
リソース
私たちは誰でしょう
3. ビューコンポーネントの構築
3.1 概要

この章ではアプリケーションのビュー コンポーネントを作成するタスクに注目します。 それは主にJavaServer Pages(JSP)技術を使用して、作られるものです。 特にStrutsは国際化されたアプリケーションのビルドをサポートしています。 入力フォームによる対話的な処理も同様です。 ビューコンポーネントと関係した他の幾つかのトピックも簡単に解説します。

3.2 国際化されたメッセージ

数年前までは、アプリケーションの開発者は、 自分の国の住民だけをサポートしていればよいと考えていました。 そこでは、ただ1つ(ときどき2つ)の言語と日付、数値、貨幣のような量を表すのに1種類の方法しか使用されていいませんでした。 しかしながら、Webテクノロジベースのアプリケーション開発の爆発も、 インターネットおよび他の広くアクセス可能なネットワーク上のアプリケーションの配置も、 多くの場合に、目に見えない国境を与えていました。 しかし、インターネットおよび、他の広くアクセス可能なネットワークと同様に、 Webテクノロジベースのアプリケーション開発は、多くの場合において国境をなくしました。 これは、アプリケーションが(もしシャレが許されるならば)国際化 (“i”と“n”の間の文字数が18なので、「i18n」と呼ばれます) と、地域化のサポートの必要性に形を変えました。

Javaプラットフォーム上のStruts はアプリケーションの国際化と地域化を助けます。 よく知られている重要な概念は以下のとおりです

  • Locale - 国際化をサポートするJavaの基本クラスは、 java.util.Localeです。 それぞれのLocaleは特定の国と言語(オプション言語バリエーションの追加)を表します。 そしてまた、数値と日付のようなものの為のフォーマットのセットを仮定しています。
  • ResourceBundle - java.util.ResourceBundleクラスは複数言語のメッセージを サポートする基本的なツールを提供します。 詳しくは、ResoruceBundleクラスのJavadocと、 JDKのリリースに同封の国際化に関するドキュメントの情報を参照してください。
  • PropertyResourceBundle - ResourceBundleの標準実装のうちの1つは、 初期化プロパティファイルで使っているシンタックス“name=value” を用いてリソースを定義します。 これは、Webアプリケーションで使われるメッセージのリソースバンドルを用意する場合にとても便利です。 なぜなら、これらメッセージは一般的なテキストだからです。
  • MessageFormat - java.text.MessageFormatクラスは、 ランタイムに指定された引数によってメッセージ文字列 (この場合、メッセージはリソースバンドルから検索されたもの) の一部を置き換える事を可能にします。 これは文章を作成している時に有効です。 しかし、単語は異なる言語で、異なる順に現れるでしょう。 メッセージ中のプレースホルダ文字列{0}は、 第1のランタイム引き数と入れ替えられ、{1}は第2の引き数などと入れ替えられます。
  • MessageResources - Strutsのクラスorg.apache.struts.util.MessageResources を使うと、リソースバンドルのセットをデータベースのように扱うことができ、サーバ自身が動いているデフォルトの Localeの代わりに、特定の Locale(通常は現在のユーザに関連付けられている)の特定のメッセージ文字列を要求することができます。

Strutsのようなフレームワークで国際化サポートは、ユーザに対する文字や画像の表示 の国際化に限られていることに注意してください。Localeで指定された入力方法 (日本語や中国語、韓国語のような言語と共に使われる)は、クライアントデバイス (通常はWebブラウザ)に依存します。

国際化されたアプリケーションでは、使用するプラットフォームの JDK のドキュメントに含まれている国際化ドキュメントに記述されているステップに従って、それぞれの言語用のメッセージを含んだプロパティファイルを作成します。以下に例を示します。

ソースコードが com.mycompany.mypackage というパッケージの中に作成されていて、(起点となるディレクトリからの相対パスで)com/mycompany/mypackage というディレクトリに格納されているとします、com.mycompany.mypackage.MyResources というリソースバンドルを作成するためには、com/mycompany/mypackage ディレクトリの中に以下のファイルを作成します。

  • MyResources.properties - サーバのデフォルト言語をメッセージとして記述します。デフォルト言語が英語の場合、 このようなエントリーを記述します
  • MyResources_xx.properties - ISO言語コードが“xx”である言語で、同じメッセージを記述します (ISOコードの現在のリストへのリンクはjavadoc のリソースバンドルのページを参照してください)。 前述のメッセージのフランス語の場合は、このようなエントリーprompto.hello=Bonjour を記述します。サポートする言語と同数のファイルが必要となります。

Web アプリケーション配置指定子でコントローラサーブレットを設定するときに、初期化パラメータの中でアプリケーション用のリソースバンドルのベース名を定義する必要があります。 上に記述されたケースでは、それがcom.mycompany.mypackage.MyResourcesになるでしょう。

<servlet>
  <servlet-name>action</servlet-name>
  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  <init-param>
    <param-name>application</param-name>
    <param-value>com.mycompany.mypackage.MyResources</param-value>
  </init-param>
  <.../>
</servlet>

重要な事は、アプリケーション内のクラスパス上でリソースバンドルが見つかる事です。 別のアプローチはアプリケーションのクラスホルダーにMyResoureces.properties ファイルを格納する事です。 その後、単にアプリケーションの値として、“myResources”を指定することができます。 ただし、もし、ビルドスクリプトがターゲット"clean"の一部としてクラスを削除する場合、 それが、削除されないように注意してください。

もし行うなら、アプリケーションのコンパイルをする場合に classesディレクトリにsrc/conf ディレクトリの内容をコピーするAntのタスクがあります。

        <!-- Copy any configuration files -->
        <copy todir="classes">
            <fileset dir="src/conf"/>
        </copy>
       
3.3 フォームとフォームBeanの相互作用

多くのWeb開発者は<input>タグのような、 HTMLの標準の機能を1つかまたは複数使用してフォームを構築します。 ユーザは、ある動作をする対話型アプリケーションを期待します。 とくにエラーハンドリングについては、現在のページ、もしくはフォームでエラーがあった場合に、 全てを再び入力する事なしに行える事を期待します。

標準のHTMLおよびJSPページでコード化する場合、 このユーザの期待に応えるのは退屈で厄介です。 例えば、ユーザー名フィールド用の入力要素は (JSPを使って)下記のようになるでしょう。

<input type="text" name="username"
      value="<%= loginBean.getUsername() %>"/>

これを正確にタイプする事は困難ですし、 プログラムのコンセプトをよく知らないHTML開発者を混乱させ、 HTMLエディタで問題を引き起こす可能性もあります。 代りに、strutsでは JSP1.1のカスタムタグライブラリに基づいて、 フォームを構築する為の包括的な機能を提供します。 上記の場合strutsでは次のようになります

<html:text property="username"/>

初期値を取得するための JavaBean を明示的に指定する必要はなく、フレームワークによって自動的に処理されます。

HTMLフォームは、時々、ファイルをuploadするのに利用されます。 多くのブラウザはこの<input type="file">要素をサポートしています。 この要素はファイルブラウズボタンを生成します。 しかし、サーバに流入してくるファイルを扱う事は開発者の責任です。 Strutsでは、普通のフォームの構築と同一の方法でこれら“multipart”フォームを扱います。 次の章では、私たちがカバーするStrutsで作成した単純なログインフォームと、 multipartフォームの例題を示します。

3.3.1 Strutsにおけるフォームの作成

単純なHTMLと標準JSPの機能を用いた場合よりも、 Strrutsでは簡単にフォームが扱えるという事を、ログインフォームの完全な例を示して 解説します。logon.jspと名づけられた以下のページ (Strutsに含まれている例題アプリケーションに基づいています) を参照してください。


<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-html.tld"
        prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld"
        prefix="bean" %>
<html:html>
<head>
<title>
  <bean:message key="logon.title"/>
</title>
<body bgcolor="white">
<html:errors/>
<html:form action="/logon" focus="username">
<table border="0" width="100%">
  <tr>
    <th align="right">
      <html:message key="prompt.username"/>
    </th>
    <td align="left">
      <html:text property="username"
                     size="16"/>
    </td>
  </tr>
  <tr>
    <th align="right">
      <html:message key="prompt.password"/>
    </th>
    <td align="left">
      <html:password property="password"
                         size="16"/>
    </td>
  </tr>
  <tr>
    <td align="right">
      <html:submit>
        <bean:message key="button.submit"/>
      </html:submit>
    </td>
    <td align="right">
      <html:reset>
        <bean:message key="button.reset"/>
      </html:reset>
    </td>
  </tr>
</table>
</html:form>
</body>
</html:html>

次のアイテムは、前述の例に基づいて、 Struts内のフォームハンドリングの重要な特徴を示しています。

  • taglib指示は、Strutsタグライブラリー用のタグライブラリー記述子を、 どこで見つけるべきであるかJSPページコンパイラーに伝えます。 この場合、struts-beanライブラリからタグを識別するために、 "bean"というプレフィックスを、struts-htmlライブラリからタグを識別するために、 "html"というプレフィックスを使います。
  • このページは、このアプリケーション用の資源をすべて含んでいる MessageResourcesオブジェクトから、 国際化されたメッセージ文字列を探すために、 メッセージタグのいくつかを使用します。 このページが動作するためには,以下のメッセージキーがリソースの中に定義されている必要があります。
    • logon.title - ログオンページのタイトル
    • prompt.username - "Username:" プロンプト文字列
    • prompt.password - "Password:" プロンプト文字列
    • button.submit - ボタンのラベルの "Submit"文字列
    • button.reset - ボタンのラベルの"Reset" 文字列
    ユーザがログオンする場合、アプリケーションはユーザのセッションに Localeオブジェクトを格納することができます。 このLocaleは適切な言語でメッセージを選択するために使用されます。 これは、格納されたLocaleオブジェクトを単純に変更するだけで、 ユーザによって言語およびすべてのメッセージを自動的に切り替えられるというオプションを、 容易にインプリメントする事が出来ます。
  • エラータグは、ビジネスロジックコンポーネントによって保存されたエラーメッセージがある場合、全てのエラーメッセージを表示します。そうでない場合は何も表示しません。
  • フォームタグは指定された属性に基づいて HTMLの<form> 要素を表現します。このタグはフォーム内の全てのフィールドをlogonForm というキーで格納されているセッションスコープのFormBean に関連付けます。Struts開発者は、StrutsのActionFormクラスのサブクラスである、このform beanのJava実装を提供します。この bean は bean のプロパティ名とマッチする全ての入力フィールドに初期値を提供するのに使用されます。 適切なBeanが見つからない場合、指定されたJavaクラス名を用いて、新しいBeanが自動的に作成されます
  • フォームBeanはまた、Strutsコンフィグレーションファイルでも指定可能です。 その場合、NameとTypeはHTMLフォームでは省略可能です。 (詳しくは“ The Action Mappings Configuration File ” を参照してください.)
  • テキストタグはHTMLの <input> 要素の“text”タイプを表現します。 この場合、ブラウザのスクリーンに占める文字ポジションの数を同様に指定します。 このページが実行されたとき、表示される値は、対応するBeanのusernameプロパティとなります (それは、getUsername()の戻り値です)
  • パスワードタグも同様です。違いは、ユーザがパスワードをタイプすると、ブラウザが入力された値の代りに、アスタリスク文字を表示する点です。
  • サブミットタグとリセットタグは対応するボタンをフォームの最後に生成します。 それぞれのボタンのテキストラベルは、プロンプトのように、メッセージタグを使って生成されます。 その結果これらの値は国際化されます

multipartフォームの扱いはさらに簡単です。 明白にmultipartフォームを作成する場合、 少なくとも1つは "file"タイプのインプットをもちます。 マルチパートフォーム作成の最初のステップは、struts-html タグライブラリを用いて作るプレゼンテーションページです


<%@page language="java">
<%@taglib uri="/WEB-INF/struts-html.tld"
       prefix="html">
<html:form action="uploadAction.do">
  Please Input Text:
  <html:text property="myText"><br/>
  Please Input The File You Wish to Upload:<br/>
  <html:file property="myFile"><br />
  <html:submit />
</html:form>

次のステップではActionForm Beanを作成します


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
public class UploadForm extends ActionForm {
  protected String myText;
  protected FormFile myFile;
  public void setMyText(String text) {
    myText = text;
  }
  public String getMyText() {
    return myText;
  }
  public void setMyFile(FormFile file) {
    myFile = file;
  }
  public FormFile getMyFile() {
    return myFile;
  }
}

javadocs のFormFileのメソッドを参照してください。 ファイルのアップロードの方法を提供しています。 さらに、javadocのActionServlet と ActionMapping の様々な引数を参照してください。 ファイルアップロードの変更の指定方法がわかります。 基本的には action クラスの perform() メソッドで((UploadForm) form).getMyFile() を呼び出して formfileを取得し、必要な処理を行います。

3.3.2 サポートされた入力フィールドのタイプ

Struts は 以下の全ての入力フィールドの型に対して HTML tag を定義しています。ハイパーリンクをたどると、対応するリファレンス情報を参照することができます。

全てのケースで、フィールドタグはformタグの ネスト内にある必要があります。その結果、フィールドは、 どのBeanを表示の初期化の値として使うかを知る事になります。

3.3.3 その他の便利なプレゼンテーションタグ

プレゼンテーションを作成する際に有用なタグがいくつかあります。個別のタグライブラリの詳しい情報についてはドキュメントとタグ開発者ガイドを参照してください。

  • [logic] iterateは、 指定されたコレクション(EnumerationやHashtable,Vectorまたはオブジェクトの配列です) のそれぞれの要素の分だけタグのボディを繰り返します。
  • [logic] presentは、 どの属性が指定されたかに依存します。このタグは現在のリクエストをチェックします。 そして、もし指定された値が存在する場合にのみ、 このタグのボディとして入れ子にされたものを評価します。 属性のうちの1つだけがこのタグの中で使用された場合で、 property属性を使用していなければ、name属性が必須となります。 属性には、cookie,header,name,parameter,property,role, scope, user が含まれます。
  • [logic] notPresentは、 presentと相反するタグで、指定された属性が存在しない場合、notPresentは同じ機能を提供します。
  • [html] linkは、 HTML <a> 要素は、指定されたURLへのアンカー定義、あるいはハイパーリンクを生成します またクッキーサポートが無い状態でセッション状態を維持するために、 自動的にURLエンコーディングを適用します
  • [html] img は、 <html:link>が出来る事と同じ方法で、 動的に"src"または"lowsrc"属性によって指定されたURLを変更する機能を備えた HTML <img> 要素を生成します
  • [bean] parameterは、 リクエストパラメータで指定された値を取り出し、そしてStringとString[]タイプ のページスコープ属性の結果を定義します。
3.3.4 自動的なフォームのバリデーション

前述のフォームとBeanの相互作用に加えて、Strutsでは、 入力フィールドの値を受け取った時にチェックする機能を提供しています。 この機能を利用するには、 あなたのActionFormクラスのメソッドを下記のようにオーバライドします。

public ActionErrors
  validate(ActionMapping mapping,
    HttpServletRequest request);

validate() メソッドは、Beanのプロパティを設定した後に、 対応するアクションクラスのperform()メソッドの呼び出しの前に、 コントローラによって呼ばれます。 validate()メソッドは下記のオプションを持ちます:

  • 適切な値のバリデーションを実行し、問題が無い場合 -- nullか 長さ0の ActionErrorsインスタンスのどちらかを返します。 そして、コントローラServletは、適切なActionクラスの perform()メソッドを呼び出します。
  • 適切な値のバリデーションを実行し、問題が発見された場合 -- エラーメッセージの キー(アプリケーションのMessageResourcesバンドルにある)を含んだ ActionErrorを内容にもつ ActionErrorsインスタンスを返すと、 メッセージが表示されます。コントローラServletは、 この配列を適切なリクエスト属性に保存し、<html:errors> タグによって使えるようにします。 そして、入力フォーム(このActionMappinginputプロパティを指定した)に表示を戻します。

以前にも述べたとおり、この機能は完全にオプションです。 標準のvalidate()メソッドの戻り値はnullです。 そして、コントローラServletはあらゆる必要なバリデーションが、 アクションクラスで行われると仮定しています。

一つの一般的なアプローチは、 ActionFormのvalidate()メソッドを使って一応のバリデーションを行ない、 その後Actionからの”ビジネスロジック”のバリデーションの制御を、シンプルに実行することです。

ActionFormのバリデーションを行うオプションパッケージはナイトリビルドに含まれ、 David WinterfeldtのWebサイト から利用可能です。

3.4 その他のプレゼンテーションテクニック

JSPの標準の能力およびStrutsカスタムタグライブラリに基づいて、 完全にあなたが求めるルックアンドフィールを構築することが出来ますが、 コンポーネント再利用性の向上やメンテナンスの手間やエラーを軽減するために、他の技術の利用も検討すべきです。 いつくかの選択肢を次の章で議論します。

3.4.1 アプリケーション特有のカスタムタグ

Strutsライブラリーによって提供されるカスタムタグの機能以上に、 ユーザインタフェースを作成するのを支援するための、 アプリケーションに特有のタグを作成する事は簡単です。 Strutsに含まれるアプリケーションの例は、 このアプリケーションの実装に特有な次のタグの作成をすることによって、 この原則を説明します。

  • checkLogon - 特定のセッションオブジェクトの存在をチェックし、 そしてもしないなら、ログオンページにフォワードするように制御します。 これは、ユーザがアプリケーションの途中のページをブックマークしてログインをバイパスしようとしたり,ユーザのセッションがタイムアウトしたのを検知したりるするために使います。
  • linkSubscription - 登録のための詳細ページへのハイパーリンクを生成し、 必要なプライマリキー値またはリクエスト属性のどちらかを要求します。 ユーザと関連した登録をリストする時、およびそれらを編集するか、 または、削除するリンクを提供するときに使われます。
  • linkUser - ユーザの詳細ページへのハイパーリンクを生成します。 必要なプライマリキーのリクエスト属性を用います。

これらタグのソースコードは、 パッケージorg.apache.struts.examplesrc/exampleディレクトリに、 このアプリケーション中で使用される他のJavaのクラスと共にあります。

3.4.2 Includeによるページ構成

1つのJSPファイル内で(必要な動的データにアクセスするカスタムタグとBeanを詰め込んで)ページのプレゼンテーション全部を作る事は、 非常に一般的なデザインアプローチで、Strutsに含まれているサンプルアプリケーションでも使用しています。 しかしながら、多くのアプリケーションでは、複数の論理的に異なる部分を1つのページで表示することが要求されます。

たとえば、ポータルアプリケーションは、ポータルのホームページで利用可能な、 次の機能の能力の幾つか、または全てを持っているかもしれません。

  • このポータルのサーチエンジンへのアクセス
  • ユーザが登録したプロファイルに基づいてカスタマイズされた、 興味のあるトピックを含んだ1つ以上のニュース項目の表示
  • このポータルに関係のある議論のトピックへのアクセス。
  • もし、ポータルがフリーメールアカウントを提供可能なら、 “未読メールあり”の表示。

このサイトの様々な部分の開発を、もし作業を分割できて、 異なる開発者を割り当てられるなら、各部分の開発はより簡単になります。 JavaServerPagesテクノロジの持つinclude機能を使って、複数の結果を結合して単一の結果ページに表示することが出来ます。また、Strutsの提供するincludeタグでも同様のことが可能です。 いつ出力を結合させたいかによって、3つのタイプのincludeが利用可能です。

  • <%@ include file="xxxxx" %> 指示はjavaコードまたはJSPタグを含むファイルをインクルードできます。 含まれたファイル中のコードは、外部のJavaServer ページより前に宣言されていた変数を、 参照する事が出来ます。コードは、コンパイルされるよりも前に、 外部のJSPにインライン展開されるので、単なるHTMLよりも多くの情報を含む事ができます。
  • インクルードのアクション(<jsp:include page="xxxxx" flush="true" />)は、リクエストの時に処理されます。 そして、サーバによって透価的にハンドルされます。 とりわけ、それは、parameter 属性を使うのと同じように、 タグ内にequals を入れ子にすることにより、条件付きで実行出来る事を意味します。
  • bean:include タグは、インクルードするJSPにマップされた論理名を表す"forward"引数か、 ページコンテキストのString変数を表す"id"引数かどちらかを、JSPページ表示するために取ります。

他のアプローチは、Strutsのテンプレートタグライブラリを使う事です。 詳しくは Developer's Guideを見てください

Tilesはオリジナルのテンプレート・タグライブラリの代わりに、 いくつかの拡張と新しい能力を提供します。 TilesはNightly Build、および Cedric DumoulinのWebサイトから利用可能です。

3.4.3 イメージ描画コンポーネント

いくつかのアプリケーションは、株価レポートサイトの価格チャートのような、 なイメージの生成を必要とします。これらの要求には、一般的に2つの異なるアプローチがあります。

  • Servletリクエストを実行するハイパーリンクのURLを生成します。 Servletはグラフィックライブラリを使い、グラフィックイメージを表現し、 コンテントタイプを適切にセットします(たとえば image/gif)。 そして、ブラウザにイメージのバイトを送り返します。 あたかも、静的なファイルを受け取ったかのように表示されるでしょう
  • 要求された画像を作り出すJavaアプレットをダウンロードするのに必要なHTMLコードを生成します。 この生成されたコード中でアプレットの適切な初期化パラメータをセットするすることにより、 グラフを設定することができます。 あるいは、アプレットにこれらパラメータを受け取らせる為に、 サーバへ接続を行わせる事も出来ます。
3.4.4 テキストの描画

いくつかのアプリケーションは、XMLのようなmarkupまたはtextの動的な生成が必要です。 もし、完成したページがレンダリングされていてPrintWriterを使用して出力することができる場合、 Actionから実行させることは非常に簡単です:

           response.setContentType("text/plain"); // or text/xml
           PrintWriter writer = response.getWriter();
           // use writer to render text
           return(null);
         

Next: コントローラコンポーネントの構築


[訳注: これは黒住 幸光が翻訳しました。日本語訳に対するコメントがあれば、report@jajakarta.orgに送って下さい。]
Copyright (c) 2000-2002, Apache Software Foundation