第28章 Seam の設定と Seam アプリケーションのパッケージング


設定は複雑でつまらない場合がありますが、 大部分はゼロから作る必要はありません。 Seam を ご使用の JavaServer Faces (JSF) 実装およびサーブレットコンテナと統合するために XML が数行必要な他は、 ほとんどの部分はアプリケーションの起動に seam-gen を使用するか、Seam で提供されるサンプルアプリケーションからコピーして貼り付けるだけです。

28.1. Seam の基本設定

最初に、JSF と Seam を併用する場合に必要となる基本設定について見ていきます。

28.1.1. Seam と JSF、 サーブレットコンテナとの統合

まず Faces サーブレットを定義します。
<servlet>
   <servlet-name>Faces Servlet</servlet-name>
   <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>
         
<servlet-mapping>
   <servlet-name>Faces Servlet</servlet-name>
   <url-pattern>*.seam</url-pattern>
</servlet-mapping>
Copy to Clipboard Toggle word wrap
(適宜 URL パターンを調整できます。)
また、 Seam には web.xml ファイルに次のエントリも必要になります。
<listener> 
  <listener-class>org.jboss.seam.servlet.SeamListener</listener-class> 
</listener>
Copy to Clipboard Toggle word wrap
このリスナーは Seam のブートストラップおよびセッションとアプリケーションのコンテキストの破棄を行います。
JSF 実装の中には Seam の対話伝播と動作するサーバー側状態保存を実装していないものがあります。 フォームサブミット中の対話伝播に問題が見られる場合はクライアント側状態保存に切り替えてみてください。そのためには web.xml に次を追加します。
<context-param> 
  <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
  <param-value>client</param-value> 
</context-param>
Copy to Clipboard Toggle word wrap
JSF 仕様ではビュー状態の値の可変性が不明瞭です。 Seam は JSF ビュー状態を使ってその PAGE スコープに戻るためこれが問題となる可能性があります。 JSF-RI (JSF 参照実装) でサーバー側状態保存を使用し、特定のページビューに対してページスコープの Bean にその正確な値を維持させたい場合、 コンテキストパラメータを次のように指定する必要があります。
<context-param> 
  <param-name>com.sun.faces.serializeServerState</param-name> 
  <param-value>true</param-value> 
</context-param>
Copy to Clipboard Toggle word wrap
これを指定しないとページスコープのコンポーネントはページの最新値を含むことになり、「戻る」ボタンを使用した場合に「戻る」ページの値を含みません (詳細は 本仕様に関する問題 を参照してください)。この設定はデフォルトでは有効になっていません。 JSF ビューを各要求でシリアライズ化すると全体的なパフォーマンスが低下するためです。

28.1.2. Facelet の使用

JavaServer Pages (JSP) に推奨の Facelets を使用するには次の行を faces-config.xml に追加します。
<application> 
  <view-handler>com.sun.facelets.FaceletViewHandler</view-handler> 
</application>
Copy to Clipboard Toggle word wrap
次に以下の行を web.xml に追加します。
<context-param> 
  <param-name>javax.faces.DEFAULT_SUFFIX</param-name> 
  <param-value>.xhtml</param-value> 
</context-param>
Copy to Clipboard Toggle word wrap

28.1.3. Seam Resource Servlet

Seam Resource Servlet は Seam Remoting、 CAPTCHA (章「セキュリティ」を参照) や JSF の UI コントロールで使用されるリソースを提供します。Seam Resource Servlet の設定には web.xml に以下のエントリが必要です。
<servlet> 
  <servlet-name>Seam Resource Servlet</servlet-name> 
  <servlet-class>
    org.jboss.seam.servlet.SeamResourceServlet
  </servlet-class> 
</servlet> 
<servlet-mapping> 
  <servlet-name>Seam Resource Servlet</servlet-name> 
  <url-pattern>/seam/resource/*</url-pattern> 
</servlet-mapping>

Copy to Clipboard Toggle word wrap

28.1.4. Seam Servlet フィルタ

Seam は基本操作には Servlet フィルタを必要としません。 ただし、フィルタの使用に依存する機能がいくつかあります。 Seam では他の組み込み Seam コンポーネントを設定する場合と同じようにして Servlet フィルタを追加、設定することができます。 この設定方法を利用するにはまず web.xml にマスターフィルタをインストールする必要があります。
<filter> 
  <filter-name>Seam Filter</filter-name> 
  <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class> 
</filter> 
<filter-mapping> 
  <filter-name>Seam Filter</filter-name> 
  <url-pattern>/*</url-pattern> 
</filter-mapping>
Copy to Clipboard Toggle word wrap
Seam マスターフィルタは web.xml で指定される 1 番目のフィルタで なければなりません。これでマスターフィルタが最初に実行されます。
Seam フィルタにはいくつかの共通の属性があります。 これらに加えて以降で説明するパラメータを components.xml で設定することができます。
  • url-pattern − フィルタされる要求を指定するのに使用します。 デフォルトは全要求です。 url-pattern はワイルドカードサフィックスを許可するパターンです。
  • regex-url-pattern − フィルタされる要求を指定するのに使用します。 デフォルトは全要求です。 regex-url-pattern は要求パスに対する実際の正規表現の一致です。
  • disabled − 組み込みのフィルタの無効化に使用します。
これらのパターンは要求の URI パスに対して適合される点 (HttpServletRequest.getURIPath() を参照)、および Servlet コンテキスト名は適合が行われる前に削除される点に注意してください。
マスターフィルタを追加することにより、以下の組み込みフィルタが有効になります。

28.1.4.1. 例外処理

このフィルタは大部分のアプリケーションで必要とされ、 pages.xml に例外マッピングの機能を提供します。 また、キャッチされなかった例外が発生した場合にコミットされていないトランザクションのロールバックも行います (これは Web コンテナにより自動的に行われるはずですが、正しくこの動作を行わないアプリケーションサーバーもあります)。
デフォルトにより例外処理フィルタはすべての要求を処理しますが、以下のように components.xml<web:exception-filter> エントリを追加してこれを変更することもできます。
<components xmlns="http://jboss.com/products/seam/components" 
            xmlns:web="http://jboss.com/products/seam/web"> 
  <web:exception-filter url-pattern="*.seam"/> 
</components>
Copy to Clipboard Toggle word wrap

28.1.4.2. リダイレクトによる対話の伝播

このフィルタにより Seam はブラウザリダイレクト全体に対話コンテキストを伝播することが可能です。あらゆるブラウザリダイレクトをインターセプトし、Seam の対話識別子を指定する要求パラメータを追加します。
リダイレクトフィルタもデフォルトですべての要求を処理しますが、 components.xml の記述を以下のように調節することも可能です。
<web:redirect-filter url-pattern="*.seam"/>
Copy to Clipboard Toggle word wrap

28.1.4.3. URL の書き換え

このフィルタにより Seam は pages.xml の設定に応じてビューの URL 書き換えを適用できます。 このフィルタはデフォルトではアクティブではありませんが、 components.xml に以下の設定を追加するとアクティブにできます。
<web:rewrite-filter view-mapping="*.seam"/>
Copy to Clipboard Toggle word wrap
view-mapping パラメータは web.xml ファイルにある Faces Servlet 用に定義された Servlet マッピングに一致しなければなりません。 省略すると書き換えフィルタはパターンが *.seam であるとみなします。

28.1.4.4. マルチパートフォームの送信

この機能は Seam の ファイルアップロード JSF コントロールを使用するときに必要です。 マルチパートフォームの要求を検出すると、 multipart/form-data 仕様 (RFC-2388) に従い処理を行います。設定を上書きするためには components.xml に以下を追加します。
<web:multipart-filter create-temp-files="true" 
     max-request-size="1000000" url-pattern="*.seam"/>
Copy to Clipboard Toggle word wrap
  • create-temp-filestrue に設定するとアップロードされたファイルはメモリで保持されるのではなく一時ファイルに書き込まれます。 大容量ファイルのアップロードが予期されるときには考慮すべき重要な点となる場合があります。デフォルト設定は false です。
  • max-request-size — ファイルのアップロード要求のサイズがこの値を越えるとその要求は中断されます。 デフォルト設定は 0 (サイズ制限なし) です (ファイルアップロードのサイズは要求の Content-Length ヘッダーを読み込んで決定されます)。

28.1.4.5. 文字エンコーディング

送信されたフォームデータの文字エンコーディングを設定するフィルタです。 デフォルトではこのフィルタはインストールされていないため、 有効にするには components.xml に以下のエントリが必要です。
<web:character-encoding-filter encoding="UTF-16" 
     override-client="true" url-pattern="*.seam"/>
Copy to Clipboard Toggle word wrap
  • encoding − 使用するエンコーディングタイプです。
  • override-clienttrue に設定すると、 要求エンコーディングはその要求がすでにエンコーディングを指定しているか否かにかかわらず encoding で指定されているものに設定されます。 false に設定すると、 クライアントが要求エンコーディングをまだ指定していない場合にのみ設定されます。 デフォルト設定は false です。

28.1.4.6. RichFaces

RichFaces をプロジェクトに使用すると、Seam は RichFaces AJAX フィルタをその他すべての組み込みフィルタより先に自動的にインストールします。 このため、 web.xml に手作業で RichFaces Ajax を追加する必要はありません。
RichFaces Ajax フィルタは RichFaces JAR 群がプロジェクトにある場合にのみインストールされます。
デフォルト設定を上書きするには次のエントリを components.xml に追加します。 オプションは RichFaces Developer Guide に記載されているものと同じです。
<web:ajax4jsf-filter force-parser="true" enable-cache="true" 
     log4j-init-file="custom-log4j.xml" url-pattern="*.seam"/>
Copy to Clipboard Toggle word wrap
  • force-parser − JSF の全ページが Richfaces の XML 構文チェッカーにより強制的に検証されるようにします。 false に設定すると、AJAX の応答のみが検証され適格な XML に変換されます。 force-parserfalse に設定するとパフォーマンスは向上しますが AJAX 更新で視覚アーティファクトが生じることがあります。
  • enable-cache − フレームワーク生成のリソースのキャッシュ化を有効にします (javascript、 CSS、 イメージなど)。 カスタムの javascript や CSS を開発している場合は true に設定するとブラウザにリソースをキャッシュさせないようにします。
  • log4j-init-file − アプリケーションごとのログ記録の設定に使用されます。log4j.xml 設定ファイルにウェブアプリケーションコンテキストと相対的なパスを与えてください。

28.1.4.7. アイデンティティロギング

このフィルタは認証されたユーザー名を log4j マップ診断コンテキストに追加するため、 パターンに %X{username} を追加するとフォーマット化されたログ出力にそれを含めることができます。
デフォルトではロギングフィルタが全要求を処理します。 以下の例で示すように <web:logging-filter> のエントリを components.xml に追加するとこの動作を調整できます。
<components xmlns="http://jboss.com/products/seam/components" 
            xmlns:web="http://jboss.com/products/seam/web"> 
  <web:logging-filter url-pattern="*.seam"/> 
</components>
Copy to Clipboard Toggle word wrap

28.1.4.8. カスタムなサーブレットのコンテキスト管理

JSF Servlet 以外の Servlet に直接送信される要求は JSF のライフサイクルでは処理されません。 そこで、Seam は Seam コンポーネントにアクセスする必要のあるその他の Servlet に適用できる Servelt フィルタを提供します。
このフィルタにより、カスタムな Servlet による Seam コンテキストとの通信を可能にします。各要求の最初に Seam コンテキストを設定し、要求の終了時にこれを破棄します。このフィルタは JSFの FacesServlet には 絶対に 適用しないでください。 Seam は JSF 要求のコンテキスト管理にはフェーズリスナーを使用します。
デフォルトではこのフィルタはインストールされていないため、components.xml で有効にする必要があります。
<web:context-filter url-pattern="/media/*"/>
Copy to Clipboard Toggle word wrap
コンテキストフィルタは conversationId 要求パラメータで対話コンテキストの対話 ID が定義されることを期待します。必ず、要求に対話 IDを含めるようにしてください。
また、新たな対話 ID はクライアントに確実に伝播する必要があります。Seam は組み込みコンポーネント conversation のプロパティとして対話 ID を公開します。

28.1.4.9. カスタムフィルタの追加

Seam はフィルタをインストールすることができ、 チェーン内にフィルタを配置する場所を指定できます (フィルタを web.xml で指定すると Servlet 仕様は明確な順序を提供しません)。 @Filter アノテーションを Seam コンポーネントに追加します (Seam コンポーネントは javax.servlet.Filter を実装しなければなりません) 。
@Startup 
@Scope(APPLICATION) 
@Name("org.jboss.seam.web.multipartFilter") 
@BypassInterceptors 
@Filter(within="org.jboss.seam.web.ajax4jsfFilter") 
public class MultipartFilter extends AbstractFilter {...}
Copy to Clipboard Toggle word wrap
@Startup アノテーションを追加すると Seam 起動時にコンポーネントが使用可能となります。 バイジェクションはここでは使用できません (@BypassInterceptors)。 フィルタは RichFaces フィルタよりチェーンの下方にします (@Filter(within="org.jboss.seam.web.ajax4jsfFilter"))。

28.1.5. EJB コンテナと Seam の統合

Seam アプリケーション内の EJB コンポーネントは Seam と EJB コンテナの両方で管理されます。 Seam は EJB コンポーネントの参照を解決し、 ステートフルセッション Bean のコンポーネントのライフタイムを管理、 インターセプタで各メソッドコールに参加します。 Seam を EJB コンテナと統合するには最初にインターセプタチェーンを設定する必要があります。
SeamInterceptor を Seam EJB コンポーネントに適用します。 このインターセプタはバイジェクション、 対話区分、 ビジネスプロセスのシグナルなどの操作を処理するサーバー側の組み込みインターセプタ一式に委譲します。 アプリケーション全体に渡りこれを最も容易に行うためには、次のインターセプタ設定を ejb-jar.xml に追加します。
<interceptors> 
  <interceptor> 
    <interceptor-class>
      org.jboss.seam.ejb.SeamInterceptor
    </interceptor-class> 
  </interceptor> 
</interceptors> 
<assembly-descriptor> 
  <interceptor-binding> 
    <ejb-name>*</ejb-name> 
    <interceptor-class>
      org.jboss.seam.ejb.SeamInterceptor
    </interceptor-class> 
  </interceptor-binding> 
</assembly-descriptor>
Copy to Clipboard Toggle word wrap
セッション Bean の JNDI 内の場所を Seam に指示する必要があります。 各セッション Bean の Seam コンポーネントで @JndiName アノテーションを指定します。より適切な方法は、 EJB 名から JNDI 名を判断できるようパターンを指定することです。ただし、 EJB3 仕様ではグローバル JNDI をマッピングする標準的な方法は定義されていないため、 このマッピングはベンダー固有であり、命名規則により異なる可能性もあります。 このオプションは components.xml で指定します。
JBoss AS の場合、 正しいパターンは次のとおりです。
<core:init jndi-name="earName/#{ejbName}/local" />
Copy to Clipboard Toggle word wrap
上記の earName は Bean がデプロイされる EAR 名です。 Seam は #{ejbName} をEJB 名に置き換えるため、 最後の部分はインターフェースのタイプを表します (ローカルまたはリモート)。
EAR コンテキストの外側では (JBoss Embeddable EJB3 コンテナを使用する場合など)、 EAR がないため最初の部分は省略されて次のようなパターンになります。
<core:init jndi-name="#{ejbName}/local" />
Copy to Clipboard Toggle word wrap
複雑な過程に見えますが実際には数点の手順だけです。
まず、 EJB コンポーネントがどのように JNDI に転送されるのか見ていきます。 XML の使用を避けるために JBoss AS は前述したパターン (EAR name/EJB name/interface タイプ) を使って自動的に EJB コンポーネントにグローバル JNDI 名を割り当てます。 次のうち値が空ではない最初の値が EJB 名となります。
  • ejb-jar.xml 内の <ejb-name> エレメント
  • @Stateless@Stateful アノテーションの name 属性、 または
  • Bean クラスの簡易名
例えば、 次の EJB Bean とインターフェースが定義されているとします。
package com.example.myapp; 
import javax.ejb.Local; 

@Local 
public class Authenticator { 
  boolean authenticate(); 
} 


package com.example.myapp; 
import javax.ejb.Stateless; 

@Stateless 
@Name("authenticator") 
public class AuthenticatorBean implements Authenticator { 
  public boolean authenticate() { ... } 
}
Copy to Clipboard Toggle word wrap
EJB Bean クラスを myapp という名前で EAR にデプロイすると仮定すると、 JBoss AS で割り当てられるグローバル JNDI 名は myapp/AuthenticatorBean/local になります。 この EJB コンポーネントを authenticator という名前で Seam コンポーネントとして参照できるため、 Seam はその JNDI パターン (または @JndiName アノテーション) を使って JNDI 内で検索を行います。
他のアプリケーションサーバーの場合は EJB に EJB 参照を宣言する必要があります。 これにより JNDI 名が割り当てられます。 これには若干の XML が必要になります。 つまり、 Seam JNDI パターンを使用できるよう独自の JNDI 命名規則を確立する必要があるということです。 JBoss 規則に従うと便利な場合があります。
Seam を JBoss アプリケーションサーバー以外のサーバーと併用させる場合、 EJB 参照を 2 箇所で定義する必要があります。 Seam EJB コンポーネントを JSF (JSF ビュー内または JSF アクションリスナーとして) や Seam JavaBean コンポーネントで検索する場合は、EJB 参照を web.xml で宣言する必要があります。 次はこの例で必要となるEJB 参照です。
<ejb-local-ref> 
  <ejb-ref-name>myapp/AuthenticatorBean/local</ejb-ref-name> 
  <ejb-ref-type>Session</ejb-ref-type> 
  <local>org.example.vehicles.action.Authenticator</local> 
</ejb-local-ref>
Copy to Clipboard Toggle word wrap
この参照は Seam アプリケーション内のコンポーネントのほとんどの使用に対応します。 Seam コンポーネントを @In アノテーションを付けて別の Seam EJB コンポーネントにインジェクトできるようにしたい場合は、この EJB 参照を 2 番目の場所となる ejb-jar.xml に定義する必要があります。 こちらの方が若干複雑です。
Seam が Seam EJB コンポーネントを検索して @In で定義されるインジェクションポイントを満たすと、 コンポーネントは JNDI 内で参照される場合にのみ見つかります。 JBoss は自動的に EJB を JNDI に登録するため、 常に Web および EJB コンテナに対して使用可能です。 他のコンテナの場合は EJB を明示的に定義する必要があります。
EJB 仕様を順守するアプリケーションサーバーは EJB 参照が常に明示的に定義されている必要があります。 これらはグローバルには宣言できません。 各 JNDI リソースを EJB コンポーネントに対して個別に指定する必要があります。
RegisterAction という解決済みの名前を持つ EJB があるとすると、 次の Seam インジェクションが適用されます。
@In(create = true) Authenticator authenticator;
Copy to Clipboard Toggle word wrap
このインジェクションを動作させるには、次のように ejb-jar.xml でリンクを確立する必要もあります。
<ejb-jar> 
  <enterprise-beans> 
    <session> 
      <ejb-name>RegisterAction</ejb-name> 
      <ejb-local-ref> 
      <ejb-ref-name>myapp/AuthenticatorAction/local</ejb-ref-name> 
      <ejb-ref-type>Session</ejb-ref-type> 
      <local>com.example.myapp.Authenticator</local> 
      </ejb-local-ref> 
    </session> 
  </enterprise-beans> 
  
  ...
   
</ejb-jar>
Copy to Clipboard Toggle word wrap
コンポーネントは web.xml で参照されたのと同じようにここで参照されます。 ここで識別することにより EJB コンテキストで参照が可能となり、 RegisterAction Bean がその参照を使用できるようになります。(@In により) 任意の Seam EJB コンポーネントの各インジェクションに対して 1 つの参照を別の Seam EJB コンポーネントに追加する必要があります。 jee5/booking サンプルでこの設定例を見ることができます。
特定の EJB を別の EJB に @EJB アノテーションを付けてインジェクトすることができますが、 Seam EJB コンポーネントのインスタンスではなく EJB 参照をインジェクトすることになります。 Seam のインターセプタはいずれの メソッド呼び出し でも EJB コンポーネントに対して呼び出され、 @EJB を使用することで Seam のサーバー側のインターセプタチェーンのみを呼び出すため、 @EJB インジェクションでは動作しなくなる Seam 機能がいくつかあります (セキュリティや同時実行を行う Seam の状態管理と Seam のクライアント側インターセプタチェーンなどがこれに該当する機能です)。ステートフルセッション Bean が @EJB を使ってインジェクトされると、 必ずしもアクティブなセッションや対話にバインドするとは限らないため、 @In を使ってインジェクトを行うことをお薦めします。
すべての EJB コンポーネントに対して明示的に JNDI 名の指定を必要とするアプリケーションサーバーがあり (Glassfish など)、 時には複数回に渡り指定を必要とすることがあります。 また、 JBoss AS 命名規則に従っている場合でも Seam で使用される JNDI パターンの変更を必要とする場合があります。 たとえば、 Glassfish ではグローバル JNDI 名の先頭に自動的にプレフィックス java:comp/env が付くため、 JNDI パターンを次のように定義する必要があります。
<core:init jndi-name="java:comp/env/earName/#{ejbName}/local" />
Copy to Clipboard Toggle word wrap
トランザクション管理には、 コンテナのトランザクションを完全に認識し、 Events コンポーネントで登録されるトランザクションの成功イベントを正しく処理できるような特殊な組み込みコンポーネントを使用することをお勧めします。 コンテナ管理トランザクションがいつ終了するのかを Seam に伝えるには次の行を components.xml ファイルに追加します。
<transaction:ejb-transaction/>
Copy to Clipboard Toggle word wrap

28.1.6. 注意点

統合における最後の要件として、 Seamコンポーネントがデプロイされるアーカイブにはすべて seam.propertiesMETA-INF/seam.properties または META-INF/components.xml ファイルを配置しておく必要があります。 Web アーカイブ (WAR) ファイルの場合は、コンポーネントがデプロイされる WEB-INF/classes ディレクトリの内側に seam.properties ファイルを配置します。
Seam は起動時に Seam コンポーネントの seam.properties ファイルを持つアーカイブをすべてスキャンします。 seam.properties ファイルは空でも構いませんが、 Seam がコンポーネントを認識できるようファイルを含ませなければなりません。 これは JVM (Java Virtual Machine) が持つ制約に対処する方法です。 seam.properties ファイルを持たせない場合は components.xml にすべてのコンポーネントを明示的に記載しなければならなくなります。
トップに戻る
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2025 Red Hat