Seam リファレンスガイド
JBoss Enterprise Application Platform 5 のユーザー向け
エディッション 5.1.2
概要
第1章 Seam チュートリアル リンクのコピーリンクがクリップボードにコピーされました!
1.1. Seam サンプルの使用 リンクのコピーリンクがクリップボードにコピーされました!
examples サブディレクトリに置かれています。 登録に関する最初の例は examples/registration ディレクトリにあります。
viewディレクトリには Web ページテンプレート、イメージ、スタイルシートなどビュー関連のファイルが入っています。resourcesディレクトリにはデプロイメント記述子やその他の構成ファイルが入っています。srcディレクトリにはアプリケーションソースコードが入っています。
build.xml よりビルドし実行されるため、始める前に Ant の最新版をインストールしておく必要がある点に注意してください。
1.1.1. JBoss AS でのサンプルの実行 リンクのコピーリンクがクリップボードにコピーされました!
build.properties (ご使用の Seam installation のルートフォルダ内) の jboss.home を JBoss AS installation の場所に設定する必要があります。
ant explode と入力するとビルドとデプロイを行うことができます。 EAR (Enterprise Archive) としてパッケージ化されたサンプルは /seam-example のような URL にデプロイします。 example はサンプルフォルダの名前です。 これには例外がひとつあります。 サンプルフォルダが「seam」で始まる場合、 プレフィックスの「seam」は省略されます。 たとえば、 JBoss AS がポート 8080 で実行中の場合、 Registration サンプルの URL は http://localhost:8080/seam-registration/ になるのに対し、 SeamSpace サンプルの URL は http://localhost:8080/seam-space/ になります。
/jboss-seam-example のような URL にデプロイします。
注記
1.1.2. サンプルのテストの実行 リンクのコピーリンクがクリップボードにコピーされました!
ant test を実行することです。
1.2. 最初の Seam アプリケーション: 登録サンプル リンクのコピーリンクがクリップボードにコピーされました!
1.2.1. コードの理解 リンクのコピーリンクがクリップボードにコピーされました!
1.2.1.1. エンティティ Bean: User.java リンクのコピーリンクがクリップボードにコピーされました!
例1.1 User.java
|
EJB3 標準 @Entity アノテーションは、 User クラスがエンティティ Bean であることを示しています。
|
|
Seam コンポーネントには @Name アノテーションで指定される コンポーネント名 が必要です。この名前は Seam アプリケーション内で一意である必要があります。JSF が Seam に Seam コンポーネント名と同じ名前を持つコンテキスト変数を解決するよう指示し、コンテキスト変数が現在未定義 (null) である場合、Seam はそのコンポーネントをインスタンス化し、新しいインスタンスをコンテキスト変数にバインドします。この場合、JSF が user という変数に初めて出会うときに Seam が User をインスタンス化します。
|
|
Seam がコンポーネントをインスタンス化すると必ず、新しいインスタンスをコンポーネントの default context のコンテキスト変数にバインドします。デフォルトのコンテキストは @Scope アノテーションを使用して指定されます。User Bean はセッションスコープのコンポーネントです。
|
|
EJB 標準 @Table アノテーションは、 User クラスが users テーブルにマッピングされることを示しています。
|
| name、password、username はエンティティ Bean の永続属性です。すべての永続属性は、アクセサメソッドを定義します。これはレスポンス出力フェーズおよびモデル値の更新フェーズで JSF によりこのコンポーネントが使用されるときに必要です。
|
|
空のコンストラクタは、EJB 仕様と Seam の両方で必要です。
|
| @NotNull と @Length アノテーションは、 Hibernate Validator フレームワークの一部です。 Seam は Hibernate Validator を統合するため、 データの妥当性検証にこれを使用することができます (永続性に Hiberenate を使用していない場合でも使用できます)。
|
|
EJB 標準 @Id アノテーションは、 エンティティ Bean の主キーであることを示しています。
|
@Name と @Scope アノテーションです。 このアノテーションは、このクラスが Seam コンポーネントであることを規定しています。
User クラスのプロパティが直接 JSF コンポーネントにバインドされ、モデル値の更新フェーズで JSF により埋められていることがわかります。 JSP ページとエンティティ Bean ドメインモデル間でデータのコピーを何度も行うためのグルーコードは必要ありません。
1.2.1.2. ステートレスセッション Bean クラス: RegisterAction.java リンクのコピーリンクがクリップボードにコピーされました!
User Bean で保持されるためステートレスセッション Bean を使用します。
例1.2 RegisterAction.java
|
EJB @Stateless アノテーションはこのクラスがステートレスセッション Bean であることを示しています。
|
| @In アノテーションは Bean の属性を Seam でインジェクトされているとマークします。この場合、属性は user (インスタンス変数名) という名前のコンテキスト変数からインジェクトされます。
|
|
EJB 標準 @PersistenceContext アノテーションは、 EJB3 エンティティマネージャにインジェクトするために使用されます。
|
|
Seam @Logger アノテーションはコンポーネントの Log インスタンスをインジェクトするために使用されます。
|
|
アクションリスナーメソッドは標準 EJB3 EntityManager API を使用して、データベースとのやり取りを行い JSF 結果を返します。 これはセッション Bean であるため、register() メソッドが呼び出されるとトランザクションは自動的に開始され、 このメソッドが終了するとトランザクションがコミットされる点に注意してください。
|
|
Seam では EJB-QL 内で JSF EL 式を使用することができる点に注目してください。これにより普通の JPA setParameter() が標準 JPA Query オブジェクトで呼び出されることになります。
|
| Log API によりテンプレートから作成されたログメッセージを簡単に表示することができ、JSF EL 式を使用することも可能です。
|
|
JSF アクションリスナーメソッドは、次にどのページを表示するかを決定する文字列値の結果を返します。 null の結果 (あるいは void アクションリスナーメソッド) の場合は前のページを再表示します。純粋な JSF では、 常に JSF ナビゲーションルール を使用してその結果から JSF ビュー ID を決定するのが普通です。 複雑なアプリケーションの場合はこの間接化が役立ち、適した方法となります。ただし、このような非常に簡単なサンプルの場合 Seam では結果として JSF ビュー ID を使用することができるため、ナビゲーションルールは必要なくなります。結果としてビュー ID を使用している場合は Seam は常にブラウザリダイレクトを行う点に注意してください。
|
|
Seam は一般的な問題の解決に役立つ 組み込みコンポーネント をいくつか提供しています。 FacesMessages コンポーネントを使用すると、テンプレートで作成したエラーや成功のメッセージを表示することは容易です (Seam 2.1 では代わりに StatusMessages を使用して JSF へのセマンティック依存を取り除くことが可能です)。Seam 組み込みコンポーネントはインジェクションで取得するか、組み込みコンポーネントのクラスで instance() メソッドを呼び出すことで取得できます。
|
@Scope を明示的に指定していないので注意してください。 各 Seam コンポーネントタイプにはデフォルトのスコープがあり、明示的にスコープが指定されない場合に使用されます。ステートレスセッション Bean では、デフォルトスコープはステートレスコンテキストです。
注記
1.2.1.3. セッション Bean ローカルインタフェース : Register.java リンクのコピーリンクがクリップボードにコピーされました!
例1.3 Register.java
@Local
public interface Register
{
public String register();
}
@Local
public interface Register
{
public String register();
}
1.2.1.4. ビュー : register.xhtml と registered.xhtml リンクのコピーリンクがクリップボードにコピーされました!
例1.4 register.xhtml
<s:validateAll> のみです。 この JSF コンポーネントは含まれるすべての入力フィールドをエンティティ Bean で指定される Hibernate Validator のアノテーションに対して検証するよう JSF に指示します。
例1.5 registered.xhtml
1.2.1.5. Seam コンポーネントデプロイメント記述子 : components.xml リンクのコピーリンクがクリップボードにコピーされました!
WEB-INF ディレクトリにある components.xml と呼ばれるファイルにこの設定を与えることです。 components.xml ファイルを使用して Seam に JNDI での EJB コンポーネントの検索方法を指示することができます。
例1.6 components.xml のサンプル
org.jboss.seam.core.init という名前の Seam 組み込みコンポーネントに属する jndiPattern という名前のプロパティを設定します。 アプリケーションがデプロイされるときに、 @ 記号を使って Ant ビルドスクリプトが components.properties ファイルから正しい JNDI パターンを挿入するよう指示しています。 このプロセスの詳細については 「components.xml によるコンポーネントの設定」 を参照してください。
1.2.1.6. WEB デプロイメント記述子 : web.xml リンクのコピーリンクがクリップボードにコピーされました!
例1.7 web.xml
web.xml ファイルは Seam と JSF の両方を設定します。 ここで見る設定は Seam のアプリケーション間でほとんど変わりません。
1.2.1.7. JSF 設定 : faces-config.xml リンクのコピーリンクがクリップボードにコピーされました!
faces-config.xml が必要です。 この場合、 ビュー定義に Facelets を使用しますので、JSF にテンプレートエンジンとして Faceles を使用することを指示する必要があります。
例1.8 faces-config.xml
faces-config.xml の使用頻度は純粋な JSF に比べると非常に少なくなります。 ここでは Facelets (および JSP 以外) をビューハンドラとして有効にするためだけに使用します。
1.2.1.8. EJB デプロイメント記述子 : ejb-jar.xml リンクのコピーリンクがクリップボードにコピーされました!
ejb-jar.xml ファイルはアーカイブ中のすべてのセッション Bean に SeamInterceptor を付加することによって Seam を EJB3 と統合します。
例1.9 ejb-jar.xml
1.2.1.9. EJB 永続デプロイメント記述子 : persistence.xml リンクのコピーリンクがクリップボードにコピーされました!
persistence.xml ファイルは EJB 永続プロバイダに適切なデータソースを指示し、 またベンダー固有の設定を含んでいます。 このサンプルでは、 起動時に自動スキーマエキスポートを有効にします。
例1.10 persistence.xml
1.2.1.10. EAR デプロイメント記述子 : application.xml リンクのコピーリンクがクリップボードにコピーされました!
例1.11 登録アプリケーション
/seam-registration にバインドします。
1.2.2. 動作内容 リンクのコピーリンクがクリップボードにコピーされました!
user という名前の変数を解決するよう要求します。 その名前にはまだバインドされた値がないため (どの Seam コンテキストにも)、 Seam は user コンポーネントをインスタンス化し、結果となる User エンティティ Bean インスタンスを Seam セッションコンテキストに保管してからそれを JSF に返します。
User エンティティで指定された Hibernate Validator 制約に対してデータ整合性検証が行われるようになります。 制約に違反していると JSF はそのページを再表示します。 これ以外は、JSF はフォームの入力値を User エンティティ Bean のプロパティにバインドします。
register という名前の変数を解決するよう要求します。 Seam は前述した JNDI パターンを使ってステートレスセッション Bean を探し、それを Seam コンポーネントとしてラップしてから返します。 次に Seam がこのコンポーネントを JSF に提示すると JSF は register() アクションリスナーメソッドを呼び出します。
User エンティティをインジェクトします。
register() メソッドは入力されたユーザー名が既に存在するかどうかを調べます。 存在した場合、 エラーメッセージは FacesMessages コンポーネントでキューイングされ、 null 結果 が返されてページが再表示されることになります。FacesMessages コンポーネントはメッセージ文字列に組み込まれた JSF 式を補完し、 ビュー に JSF FacesMessage を追加します。
"/registered.xhtml"" 結果により registered.xhtml ページへのブラウザリダイレクトが発生します。JSF がページのレンダリングに到達すると、 Seam に user という名前の変数の解決を要求し、 Seam のセッションスコープから返される User エンティティのプロパティ値を使用します。
1.3. Seam のクリック可能な一覧 : メッセージサンプル リンクのコピーリンクがクリップボードにコピーされました!
<h:dataTable> を使ってクリック可能な一覧としてそれを表示します。メッセージサンプルがこの機能を示しています。
1.3.1. コードの理解 リンクのコピーリンクがクリップボードにコピーされました!
Message)、1 つのセッション Bean (MessageListBean)、1 つの JSP から構成されています。
1.3.1.1. エンティティ Bean : Message.java リンクのコピーリンクがクリップボードにコピーされました!
Message エンティティ Bean は、タイトル、テキスト、メッセージの日付と時刻、そしてメッセージが既読か否かを示すフラグを定義します。
例1.12 Message.java
1.3.1.2. ステートフルセッション Bean : MessageManagerBean.java リンクのコピーリンクがクリップボードにコピーされました!
MessageManagerBean) から構成され、 フォームにある両方のボタンに対応するアクションリスナーメソッドを定義します。 前述のサンプルと同様、 ボタンの 1 つは一覧からメッセージを選択してそのメッセージを表示します。 もう 1 つのボタンはメッセージを削除します。
MessageManagerBean の役割となります。 ユーザーがこのページに到達するにはいろいろな経路があり、 必ずしも JSF アクションがすべての経路で先行するわけではありません。 (たとえば、 お気に入りからそのページに行く場合、 必ずしも JSF アクションを呼び出す必要はありません。) したがって、 メッセージ一覧の取得作業はアクションリスナーメソッドではなく Seam の ファクトリメソッド で行われなければなりません。
例1.13 MessageManagerBean.java
| @DataModel アノテーションは、 java.util.List タイプの属性を、 javax.faces.model.DataModel インスタンスとして JSF ページに公開します。これにより、各行に対してクリック可能なリンクを持つ JSF <h:dataTable> 中の一覧を使用可能とします。 このサンプルでは、 DataModel は、 messageList という名前のセッションコンテキスト変数で利用可能です。
|
| @DataModelSelection アノテーションは Seam にクリックされたリンクに該当する List エレメントをインジェクトするよう指示します。
|
|
次に @Out アノテーションは選択された値を直接ページに公開します。クリック可能な一覧の行が選択されるたびに Message がステートフル Bean の属性にインジェクトされ、続いて message というイベントコンテキスト変数に アウトジェクト されます。
|
|
このステートフル Bean は EJB3 拡張永続コンテキスト を持っています。この Bean が存在する限り、クエリで取得されたメッセージは管理状態に留まります。そのため、ステートフル Bean への後続のメッセージ呼び出しは、 EntityManager へ明示的な呼び出しを行わずにそのメッセージを更新することができます。
|
|
初めて JSP ページに移動するとき、 messageList コンテキスト変数には値がありません。@Factory アノテーションは Seam に MessageManagerBean インスタンスを作成し、findMessages() メソッドを呼び出し、値を初期化するよう指示します。findMessages() を messages の ファクトリメソッド と呼びます。
|
| select() アクションリスナーメソッドは、 選択された Message に既読マークを付け、 データベース中のそれを更新します。
|
| delete() アクションリスナーメソッドは、 選択された Message をデータベースから削除します。
|
|
ステートフルセッション Bean の Seam コンポーネントは @Remove とマークされたパラメータを持たないメソッドを定義する 必要があります。Seam コンテキストが終了すると、Seam はステートフル Bean を削除しサーバー側の状態を消去します。
|
注記
1.3.1.3. セッション Bean ローカルインタフェース : MessageManager.java リンクのコピーリンクがクリップボードにコピーされました!
例1.14 MessageManager.java
Components.xml、 persistence.xml、 web.xml、 ejb-jar.xml、 faces-config.xml、 application.xml については前述までのサンプルとほぼ同じなので、 JSP に進みます。
1.3.1.4. ビュー: messages.jsp リンクのコピーリンクがクリップボードにコピーされました!
<h:dataTable> コンポーネントを使用した簡単なものです。繰り返しになりますが、この機能も Seam 固有ではありません。
例1.15 messages.jsp
1.3.2. 動作内容 リンクのコピーリンクがクリップボードにコピーされました!
messages.jsp ページに移動すると、 ページは messageList コンテキスト変数を解決しようとします。 この変数はまだ初期化されていないため、 Seam はファクトリメソッド findMessages() を呼び出します。 これがデータベースに問い合わせを行い DataModel を読み出します。 これにより <h:dataTable> の表示に必要な行データが提供されます。
<h:commandLink> をクリックすると、 JSF は select() アクションリスナーを呼び出します。 Seam はこの呼び出しをインターセプトして、選択された行データを messageManager コンポーネントの message 属性にインジェクトします。 アクションリスナーが実行され、 選択された Message に既読マークを付けます。 呼び出しの終わりに、 Seam は選択された Message を message コンテキスト変数にアウトジェクトします。 次に、 EJB コンテナはトランザクションをコミットし、 Message に対する変更がデータベースにフラッシュされます。 最後に、 このページが再度レンダリングされてメッセージ一覧を再表示、 その下に選択されたメッセージが表示されます。
<h:commandButton> をクリックすると、 JSF は delete() アクションリスナーを呼び出します。 Seam はこの呼び出しをインターセプトし、 選択された行データを messageList コンポーネントの message 属性にインジェクトします。 アクションリスナーが起動し、 選択された Message を一覧から削除、 EntityManager の remove() を呼び出します。 呼び出しの終わりに、 Seam は messageList コンテキスト変数を更新し、 message コンテキスト変数を消去します。 EJB コンテナはトランザクションをコミットし、 データベースから Message を削除します。 最後に、 このページが再度レンダリングされ、 メッセージ一覧を再表示します。
1.4. Seam と jBPM : todo 一覧サンプル リンクのコピーリンクがクリップボードにコピーされました!
1.4.1. コードの理解 リンクのコピーリンクがクリップボードにコピーされました!
例1.16 todo.jpdl.xml
| <start-state> ノードはプロセスの論理的な開始を表します。プロセスが開始すると、直ちに todo ノードに遷移します。
|
| <task-node> ノードは、待ち状態 を表します。 ビジネスプロセスの実行が一時停止され、1 つまたは複数のタスクが行われるのを待機します。
|
| <task> エレメントはユーザーにより実行されるタスクを定義します。このノードでは 1 つのタスクしか定義されていないため、それが完了すると実行が再開し、終了状態に遷移します。このタスクは todoList (JavaBeans の 1 つ) という Seam コンポーネントからその詳細を取得します。
|
|
タスクは生成されるとユーザーまたはユーザーグループに割り当てられる必要があります。 このサンプルでは、タスクは現在のユーザーに割り当てられ、 actor という名前の Seam 組み込みコンポーネントから取得されます (いずれの Seam コンポーネントを使ってもタスク割り当てを実行できます)。
|
| <end-state> ノードは、ビジネスプロセスの論理的な終了を定義します。 実行がこのノードに到達したとき、 プロセスインスタンスは破棄されます。
|
login.jsp を処理します。 単に actor コンポーネントを使用して jBPM actor ID を初期化します。 実際のアプリケーションではユーザー認証も必要となります。
例1.17 Login.java
Actor コンポーネントをインジェクトするために @In を使用しているのがわかります。
例1.18 login.jsp
例1.19 TodoList.java
|
description プロパティは JSP ページからユーザ入力を受け取りプロセス定義に公開して、タスクの description が設定されるようにします。
|
|
Seam @CreateProcess アノテーションは、名前付きプロセス定義のために jBPM プロセスインスタンスを生成します。
|
|
Seam @StartTask アノテーションはタスク上で作業を開始します。@EndTask はタスクを終了し、ビジネスプロセスの再開を可能にします。
|
@StartTask と @EndTask は同じメソッドには登場しません。 タスクを完了するためにはアプリケーションを使用して何らかの作業が行われる必要があるためです。
todo.jsp です。
例1.20 todo.jsp
taskInstanceList と呼ばれる Seam 組み込みコンポーネントから取得します。 この一覧は JSF フォームの中で定義されています。
例1.21 todo.jsp (taskInstanceList)
TaskInstance のインスタンスです。 以下のコードは一覧中の各タスクの特定のプロパティを表示しています。 記述内容 (Description)、 優先順 (Priority)、 納期の値 (Due Date) には入力コントロールを使用し、ユーザーはこれらの値を更新することができます。
例1.22 TaskInstance List のプロパティ
注記
#{task.dueDate} にバインドされるフィールドにはコンバータは必要ありません。
@StartTask @EndTask アノテーション付きのアクションメソッドを呼び出すことによりタスクを終了します。 タスク ID を要求パラメータとして Seam に渡します。
seam-ui.jar パッケージから Seam <s:button> JSF コントロールを使用していることに留意してください。 このボタンがタスクのプロパティを更新します。 フォームがサブミットされると、 Seam と jBPM はタスクの永続に対して変更を加えます。 アクションリスナーメソッドには必要ありません。
<h:commandButton value="Update Items" action="update"/>
<h:commandButton value="Update Items" action="update"/>
@CreateProcess アノテーション付きアクションメソッドを使って新しい項目を作成します。
1.4.2. 動作内容 リンクのコピーリンクがクリップボードにコピーされました!
todo.jsp は現在のユーザーの未解決の todo 項目の表を表示するために taskInstanceList コンポーネントを使用します (最初は何もありません)。ページは新しいタスク項目を入力するためのフォームも表示します。 ユーザーが todo 項目を入力して ボタンをクリックすると、 #{todoList.createTodo} が呼び出されます。これにより todo.jpdl.xml で定義したように todo プロセスが開始されます。
todo 状態に遷移し、 新しいタスクが作成されます。 #{todoList.description} に保存されるユーザーの入力に基づいてタスク description が設定されます。 次に、 Seam の actor コンポーネントに格納される現在のユーザーにタスクが割り当てられます。 このサンプルでは、 プロセスには追加のプロセス状態はありません。 状態はすべてタスク定義に保管されています。 プロセスとタスク情報は要求の最後でデータベースに格納されます。
todo.jsp が再表示されると、 taskInstanceList は新たに作成されたタスクを見つけて h:dataTable に表示します。 タスクの内部状態は #{task.description}、 #{task.priority}、 #{task.dueDate} の各列に表示されます。これらのフィールドはすべて編集してデータベースに保存することができます。
#{todoList.done} を呼び出します。 各ボタンは taskInstance="#{task}" を指定するため (表内のその特定行のタスク) todoList コンポーネントは完了されるタスクをはっきりと区別できます。 @StartTask と @EndTask のアノテーションがタスクをアクティブにして直ちに終了します。 次にオリジナルのプロセスが done 状態に遷移し (プロセス定義に従い) 終了します。 タスクとプロセスの状態がいずれもデータベース内で更新されます。
todo.jsp が再表示されると、 完了したタスクは taskInstanceList に表示されなくなります。このコンポーネントは未完了のタスクのみを表示するためです。
1.5. Seam ページフロー : 数字当てゲームサンプル リンクのコピーリンクがクリップボードにコピーされました!
1.5.1. コードの理解 リンクのコピーリンクがクリップボードにコピーされました!
例1.23 pageflow.jpdl.xml
| <page> エレメントは待ち状態を定義し、そこではシステムは特定の JSF ビューを表示し、ユーザー入力を待ちます。view-id は純粋な JSF ナビゲーションルールで使用されているのと同じ JSF ビュー ID です。ページに移動すると redirect 属性は Seam に post-then-redirect を使用するよう指示します (これにより使い易いブラウザ URL となります)。
|
| <transition> エレメントは JSF 結果に名前を付けます。JSF アクションがその結果になると遷移が引き起こされます。jBPM 遷移アクションが呼び出された後、実行はページフローグラフの次のノードに進みます。
|
|
遷移の <action> は jBPM の遷移が起こるときに発生するという点以外は、JSF アクションのようなものです。遷移アクションはどの Seam コンポーネントでも呼び出すことが可能です。
|
| <decision> ノードはページフローを分岐させ、 JSF EL 式を評価することによって次に実行するノードを決定します。
|
numberGuess.jspx です。
例1.24 numberGuess.jspx
guess 遷移の名前付けを行っていることに注意してください。
win.jspx ページはごく普通のものです。
例1.25 win.jspx
lose.jspx はほぼ同じですのでここでは記載しません。
例1.26 NumberGuess.java
|
初めて JSP ページが numberGuess コンポーネントを求めると、Seam によりそのページに対し新しいコンポーネントが作成され、@Create メソッドが呼び出され、コンポーネントがそれ自体を初期化することができます。
|
例1.27 pages.xml
1.5.2. 動作内容 リンクのコピーリンクがクリップボードにコピーされました!
numberGuess.jspx から始まります。 ページが初めて表示されると、 pages.xml 設定は対話をアクティブにし numberGuess ページフローをその対話と関連付けます。 ページフローは start-page タグから開始されるので (待機 状態) numberGuess.xhtml が表示されます。
numberGuess コンポーネントを参照し、 これにより新しいインスタンスが生成され対話に保管されます。 @Create メソッドが呼び出され、 ゲームの状態が初期化されます。 ビューは h:form を表示し、ユーザーは #{numberGuess.currentGuess} を編集できます。
guess アクションを引き起こします。 Seam はアクションを処理するためにページフローを参照し、 このページフローが evaluateGuess を呼び出し (推測した数字と numberGuess コンポーネント内の最小と最大の候補を更新)、 evaluateGuess 状態に遷移します。
evaluateGuess 状態は #{numberGuess.correctGuess} の値をチェックし、 win または evaluatingRemainingGuesses 状態のいずれかに遷移します。 数字が間違っていたとすると、ページフローは evaluatingRemainingGuesses に遷移します。 これは決定する状態でもあり、 ユーザーがまだ数字当てを続行できるか否かを決定する #{numberGuess.lastGuess} 状態をテストします。 続行できる場合は (lastGuess が false) 最初の displayGuess 状態に戻ります。 これはページの状態となるため、関連ページの /numberGuess.jspx が表示されます。 また、 このページにはリダイレクトエレメントが含まれるため、 Seam はリダイレクトをユーザーのブラウザに送信し、 それがプロセスを再び開始します。
win または lose の遷移のいずれかが呼び出されると、 ユーザーは /win.jspx または /lose.jspx にそれぞれ移動されます。 いずれの状態も Seam が対話を終了、 ゲームとページフロー状態の保持を中止、 ユーザーを最終ページへとリダイレクトすることを指定します。
cheat トランザクションに注目してください。これはサブプロセスを読み込みその特定の流れを処理します。 このアプリケーションではこのプロセスは余分ですが、 理解し易くするために複雑なページフローを細分化してより簡単な構造にする方法を示しています。
1.6. Seam アプリケーションの全容 : ホテル予約サンプル リンクのコピーリンクがクリップボードにコピーされました!
1.6.1. はじめに リンクのコピーリンクがクリップボードにコピーされました!
- ユーザー登録
- ログイン
- ログアウト
- パスワード設定
- ホテル検索
- ホテル選択
- 部屋予約
- 予約確認
- 現在の予約一覧
1.6.2. 予約サンプルの概要 リンクのコピーリンクがクリップボードにコピーされました!
http://localhost:8080/seam-booking/ をポイントするとアクセスできます。
AuthenticatorActionはログイン認証ロジックを提供します。BookingListActionは現在ログインしているユーザーのために現状の予約を取得します。ChangePasswordActionは現在ログインしているユーザーのパスワードを更新します。HotelBookingActionは予約と確認の機能を実装します。 対話 として実装されるため、 このアプリケーションの中で最も重要なクラスのひとつになります。HotelSearchingActionはホテル検索の機能を実装しています。RegisterActionは新しいシステムユーザーを登録します。
Hotelはホテルを表すエンティティ Bean です。Bookingは現在の予約を表すエンティティ Bean です。Userはホテル予約ができるユーザーを表すエンティティ Bean です。
1.6.3. Seam 対話の理解 リンクのコピーリンクがクリップボードにコピーされました!
HttpSession に追加されます。
HttpSession に保管された状態にも同様の問題が見られます。 HttpSession は実際のセッションデータ (ユーザーとアプリケーション間の全要求に共通となるデータ) の保存については問題ありませんが、個別要求のシリーズに関連するデータの場合は問題となります。 ここで保存される対話は複数のウィンドウや戻るボタンをクリックした場合にすぐに分解してしまいます。 プログラミングに注意しないと HttpSession にあるデータも増大し、セッションのクラスタ化を困難にします。 こうした手法から生じる問題に対応するためのメカニズムを開発するのは簡単ではありません (異なる同時対話に関連するセッション状態を分離して、 ひとつの対話が中断したら対話状態が必ず破棄されるようフェイルセーフを組み込みます)。
例1.28 HotelSearchingAction.java
|
EJB 標準 @Stateful アノテーションは、 このクラスがステートフルセッション Bean であることを識別しています。 ステートフルセッション Bean は、 デフォルトで対話コンテキストのスコープを持ちます。
|
| @Restrict アノテーションはコンポーネントにセキュリティ制限を適用します。 コンポーネントへのアクセスを制限し、 ログインしているユーザーにのみアクセスを許可します。「セキュリティ」の章では Seam におけるセキュリティについてさらに詳細に説明します
|
| @DataModel アノテーションは JSF ListDataModel として List を公開します。これにより検索画面でのクリック可能な一覧の実装が容易になります。このサンプルでは、ホテル一覧が hotels という名前の対話変数で ListDataModel としてページに公開されています。
|
|
EJB 標準の @Remove アノテーションはアノテーションが付けられたメソッドが呼び出された後ステートフルセッション Bean が取り除かれてその状態が破棄されることを規定しています。 Seam では、 すべてのステートフルセッション Bean はパラメータなしの @Remove メソッドを定義しなければなりません。Seam がセッションコンテキストを破棄するとこのメソッドが呼び出されます。
|
例1.29 main.xhtml
|
RichFaces Ajax <a:support> タグを使用すると、onkeyup のような JavaScript イベントの発生時に、非同期の XMLHttpRequest により JSF アクションイベントリスナーが呼び出されます。さらに良いことには reRender 属性により非同期の応答を受け取ると JSF ページの一部を表示し、一部のページを更新することが可能です。
|
|
RichFaces Ajax <a:status> タグを使用すると、非同期の要求が返されるのを待つ間に動画イメージを表示させます。
|
|
RichFaces Ajax <a:outputPanel> タグは非同期要求によって再レンダリング可能なページの領域を定義します。
|
|
Seam <s:link> タグを使用すると、JSF アクションリスナーを普通の (非 JavaScript) HTML リンクにつなげることができます。標準 JSF <h:commandLink> と比べて有利な点は、「新しいウィンドウで開く」や「新しいタブで開く」という動作を維持することです。パラメータ #{hotelBooking.selectHotel(hot)} 付きのメソッドバインディングを使用している点に注目してください。これは標準 Unified EL では不可能ですが、Seam はすべてのメソッドバインディング式でパラメータを使用できるよう EL を拡張します。
ナビゲーションのルールは WEB-INF/pages.xml に記載されています。詳細は 「ナビゲーション」 で説明します。
|
HotelBookingAction の selectHotel() メソッドに渡します。 ここで実際の作業が発生します。
例1.30 HotelBookingAction.java
|
この Bean は EJB3 拡張永続コンテキスト を使用するため、 エンティティインスタンスはステートフルセッション Bean のライフサイクル全体に対して管理されたままとなります。
|
| @Out アノテーションはメソッド呼び出しの後に属性値がコンテキスト変数に アウトジェクト されることを宣言します。このサンプルでは、アクションリスナーの呼び出しが完了するごとに、hotel という名前のコンテキスト変数が hotel インスタンス変数の値に設定されます。
|
| @Begin アノテーションは、 アノテーション付きメソッドが 長期実行の対話 を開始することを指定するため、現在の対話コンテキストは要求の終わりに破棄されません。その代わりに、現在のウィンドウからのあらゆる要求に再度関連付けられ、非アクティブな対話によるタイムアウトまたは適合する @End メソッドにより破棄されます。
|
| @End アノテーションはアノテーション付きメソッドが現在の長期実行の対話を終了することを指定します。したがって要求の終わりで現在の対話コンテキストは破棄されます。
|
|
この EJB remove メソッドは Seam が対話コンテキストを破棄すると呼び出されます。このメソッドを定義するのを忘れないようにしてください。
|
HotelBookingAction は選択、 予約、 予約確認を実装するすべてのアクションリスナーのメソッドを持っており、 この操作に関連する状態をそのインスタンス変数に保持しています。 このコードは HttpSession 属性の取得と設定に比べるとより明確でかつシンプルです。
1.6.4. Seam デバッグページ リンクのコピーリンクがクリップボードにコピーされました!
seam-debug.jar も含みます。 Seam デバッグページの使用を有効にするには、 Facelets と一緒に WEB-INF/lib にこの jar をデプロイし、 init コンポーネントの debug プロパティを以下のように設定します。
<core:init jndi-pattern="@jndiPattern@" debug="true"/>
<core:init jndi-pattern="@jndiPattern@" debug="true"/>
http://localhost:8080/seam-booking/debug.seam をポイントするだけです。
1.7. ネストされた対話 : ホテル予約サンプルの拡張 リンクのコピーリンクがクリップボードにコピーされました!
1.7.1. はじめに リンクのコピーリンクがクリップボードにコピーされました!
1.7.2. ネストされた対話の理解 リンクのコピーリンクがクリップボードにコピーされました!
例1.31 RoomPreferenceAction.java
| hotel インスタンスは対話コンテキストからインジェクトされます。ホテルは 拡張永続コンテキスト により読み込まれるため、エンティティは対話全体を通じて管理されたままとなります。これにより、単に関連付けることで、@Factory メソッドから availableRooms を遅延して読み込むことができます。
|
| @Begin(nested=true) が出現すると、 ネストされた対話は対話スタックにプッシュされます。 ネストされた対話中で実行する場合、 コンポーネントはまだ外側の対話状態すべてにアクセスできますが、 ネストされた対話の状態コンテナに値を設定しても対話の外側には影響しません。 また、 ネストされた対話は同じ外側の対話に対して同時並行的にスタックして存在することが可能で、それぞれの状態は独立しています。
|
| roomSelection は @DataModelSelection に基づいた対話にアウトジェクトされます。ネストされた対話は独立したコンテキストを持つので、roomSelection は新しいネストされた対話にのみ設定されることに留意してください。 ユーザーが別のウインドウまたはタブで異なる選択をした場合、新しいネストされた対話が開始されます。
|
| @End アノテーションは対話スタックをポップしてから外側の対話を再開します。roomSelection は対話コンテキストと共に破棄されます。
|
nestedbooking サンプルでは、 対話スタックは外部の長期実行の対話 (予約) とネストした各対話 (部屋選択) から構成されます。
例1.32 rooms.xhtml
|
EL から求められると、 RoomPreferenceAction に定義された @Factory メソッドにより #{availableRooms} がロードされます。@Factory メソッドは、@DataModel インスタンスとして現在のコンテキストに値をロードするために 1 度だけ実行されます。
|
| #{roomPreference.selectPreference} アクションを呼び出すことにより、行が選択され @DataModelSelection に値が設定されます。 そして値はネストされた対話コンテキストにアウトジェクトされます。
|
|
日付を変更すると単純に /book.xhtml に戻されます。 まだ対話をネストしていないため (選択された部屋がない)、 現在の対話は単に再開可能であることに留意してください。<s:button> コンポーネントは /book.xhtml ビューを表示するときに単に現在の対話を伝播します。
|
HotelBookingAction の動作を拡張して選択した部屋の予約を確認する方法を示しています。
例1.33 HotelBookingAction.java
|
動作に @End(root=true) アノテーションを付けるとルートの対話を終了させます。 これは効率的に対話スタック全体を破棄します。 対話が終了したらその中にネストされた対話も終了されます。 ルートはオリジナルの対話であるため、これが予約の確認が終了したら作業領域に関連付けられたすべての状態を破棄して解放するシンプルな方法です。
|
| roomSelection はユーザー確認で booking にのみ関連付けられます。 ネストされた対話コンテキストに値をアウトジェクトしても外部の対話には影響ありませんが、 外側の対話からインジェクトされるオブジェクトは参照によりインジェクトされます。 つまり、 これらのオブジェクトに対する変更はすべて親の対話で反映されるだけでなく、 他の同時にネストされた対話にも反映されます。
|
|
取り消し動作に @End(root=true, beforeRedirect=true) アノテーションを付与するだけで、 作業領域に関連するすべての状態を容易に破棄、 解放してからユーザーをホテル選択ビューにリダイレクトさせることができます。
|
1.8. Seam と jBPM を使ったアプリケーションの全容 : DVD ストアサンプル リンクのコピーリンクがクリップボードにコピーされました!
dvdstore ディレクトリから起動できます。
1.9. ブログサンプルを使ったブックマーク可能な URL の説明 リンクのコピーリンクがクリップボードにコピーされました!
1.9.1. 「プル」型 MVC の使用 リンクのコピーリンクがクリップボードにコピーされました!
index.xhtml Facelets ページの一部は最新のブログエントリの一覧を表示しています。
<h:dataTable> で使用される #{blog.recentBlogEntries} データは要求されると Seam の blog というコンポーネントにより遅延して読み出されます(「プルされる」)。 この制御の流れは従来の動作ベースの Web フレームワーク Struts で使用されているものとは逆です 。
例1.34
|
このコンポーネントは Seam 管理永続コンテキスト を使用しています。 これまで見てきた他のサンプルとは異なり、 この永続コンテキストは EJB3 コンテナではなく Seam によって管理されます。 永続コンテキストは Web 要求全体におよび、 ビューでフェッチしていない関連にアクセスすると発生する例外を回避することができます。
|
| @Unwrap アノテーションは Seam にクライアントに対する実際の BlogService コンポーネントではなく Blog メソッドの戻り値を与えるよう指示します。 これが Seam の マネージャコンポーネントパターン です。
|
1.9.2. ブックマーク可能な検索結果ページ リンクのコピーリンクがクリップボードにコピーされました!
menu.xhtml に定義され、Facelet テンプレートの template.xhtml で含まれます。
http://localhost:8080/seam-blog/search/ のようなブックマーク可能な URL を取得するには、フォームでサブミットされる値をその URL に含ませる必要があります。 JSF でこれを行うのは簡単ではありませんが、 Seam なら ページパラメータ と URL の書き換え の 2 つの機能があれば行うことができます。 いずれも WEB-INF/pages.xml で定義します。
searchPattern 要求パラメータを #{searchService.searchPattern} が保持する値にリンクするようページパラメータが Seam に指示します。 Seam は URL の状態ととアプリケーションの状態を結ぶリンクを管理する役割を担います。
book の検索 URL は、通常 http://localhost:8080/seam-blog/seam/search.xhtml?searchPattern=book です。Seam は書き換えのルールを使ってこの URL を簡略化することが可能です。/search/{searchPattern} パターンの最初の書き換えルールには、search.xhtml の URL が searchPattern 要求パラメータを含む場合は常にその URL は簡略化された URL に圧縮されることが可能であると記述しています。このため、前述した URL (http://localhost:8080/seam-blog/seam/search.xhtml?searchPattern= book) は、http://localhost:8080/seam-blog/search/book と記述することが可能です。
components.xml で書き換えフィルタを有効にすることだけです。
<web:rewrite-filter view-mapping="/seam/*" />
<web:rewrite-filter view-mapping="/seam/*" />
search.xhtml ページに移動します。
1.9.3. RESTful アプリケーションの「プッシュ」型 MVC の使用 リンクのコピーリンクがクリップボードにコピーされました!
entry.xhtml にページアクションを使用しています。
注記
entryAction コンポーネントの動作は Struts のような従来のプッシュ型 MVC アクション指向のフレームワークでのアクションクラスの動作とよく似ています。
pages.xml でも宣言されます。
注記
entry.xhtml ページが要求されると Seam はまずページパラメータ blogEntryId をそのモデルにバインドします。 URL を書き換えているため blogEntryId パラメータ名は URL に表れないことを思い出してください。 次に Seam はページアクションを実行して、 必要なデータ blogEntry を読み出し、 それを Seam イベントコンテキスト内に配置します。 最後に以下を表示させます。
EntryNotFoundException 例外が送出されます。 この例外は 505 エラーではなく 404 エラーにさせたいので例外クラスにアノテーションを付けます。
第2章 移行 リンクのコピーリンクがクリップボードにコピーされました!
2.1. Seam 1.2.x から Seam 2.0 への移行 リンクのコピーリンクがクリップボードにコピーされました!
2.1.1. JavaServer Faces 1.2 への移行 リンクのコピーリンクがクリップボードにコピーされました!
web.xml に次の変更を行う必要があります。
- MyFaces の
StartupServletContextListenerを削除します。 - AJAX4JSF フィルタ、 マッピング、
org.ajax4jsf.VIEW_HANDLERSコンテキストパラメータを削除します。 org.jboss.seam.web.SeamFilterの名前をorg.jboss.seam.servlet.SeamFilterに変更します。org.jboss.seam.servlet.ResourceServletの名前をorg.jboss.seam.servlet.SeamResourceServletに変更します。web-appのバージョンを2.4から2.5に変更します。名前空間 URL でj2eeをjavaeeに変更します。 たとえば、Copy to Clipboard Copied! Toggle word wrap Toggle overflow
SeamExceptionFilter と SeamRedirectFilter を web.xml に明示的に宣言せずに SeamFilter を web.xml に宣言することができます。
javax.faces.STATE_SAVING_METHOD コンテキストパラメータで定義します。
faces-config.xml に以下の変更が必要になります。
TransactionalSeamPhaseListenerまたはSeamPhaseListenerの宣言を使用している場合は削除します。SeamELResolver宣言を使用している場合は削除します。SeamFaceletViewHandler宣言を標準のcom.sun.facelets.FaceletViewHandlerに変更してからそれが有効になっていることを確認します。- ドキュメント上の DTD を削除して XML Schema 宣言をその
<faces-config>ルートタグに追加します。Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.1.2. コードの移行 リンクのコピーリンクがクリップボードにコピーされました!
- 永続関連のコンポーネントは
org.jboss.seam.persistenceに移動しました。 - jBPM 関連のコンポーネントは
org.jboss.seam.bpmに移動しました。 - JSF 関連のコンポーネント、 特に
org.jboss.seam.faces.FacesMessagesはorg.jboss.seam.facesに移動しました。 - サーブレット関連のコンポーネントは
org.jboss.seam.webに移動しました。 - 非同期に関連するコンポーネントは
org.jboss.seam.asyncに移動しました。 - 国際化関連のコンポーネントは
org.jboss.seam.internationalに移動しました。 - ページフローのコンポーネントは
org.jboss.seam.pageflowに移動しました。 - ページコンポーネントは
org.jboss.seam.navigationに移動しました。
- BPM 関連のアノテーションは
org.jboss.seam.annotations.bpmパッケージに含まれています。 - JSF 関連のアノテーションは
org.jboss.seam.annotations.facesパッケージに含まれています。 - インターセプタのアノテーションは
org.jboss.seam.annotations.interceptパッケージに含まれています。 - 非同期に関連するアノテーションは
org.jboss.seam.annotations.asyncパッケージに含まれています。 @RequestParameterはorg.jboss.seam.annotations.webパッケージに含まれています。@WebRemoteはorg.jboss.seam.annotations.remotingパッケージに含まれています。@Restrictはorg.jboss.seam.annotations.securityパッケージに含まれています。- 例外処理のアノテーションは
org.jboss.seam.annotations.exceptionパッケージに含まれています。 @Intercept(NEVER)ではなく@BypassInterceptorsを使用します。
2.1.3. components.xml の移行 リンクのコピーリンクがクリップボードにコピーされました!
components.xml を新しいスキーマと名前空間で更新する必要があります。
org.jboss.seam.foobar の形式をとっていました。 新しい名前空間の形式は http://jboss.com/products/seam/foobar になり、 スキーマの形式は http://jboss.com/products/seam/foobar-2.0.xsd です。 components.xml ファイルで名前空間とスキーマの形式を更新する必要があります。 これにより URL は移行先となる Seam のバージョン (2.0 または 2.1) に対応するようになります。
<core:managed-persistence-context>を<persistence:managed-persistence-context>で置換します。<core:entity-manager-factory>を<persistence:entity-manager-factory>で置換します。<core:manager/>エレメントからconversation-is-long-runningパラメータを削除します。<core:ejb/>を削除します。<core:microcontainer/>を削除します。<core:transaction-listener/>を<transaction:ejb-transaction/>で置換します。<core:resource-bundle/>を<core:resource-loader/>で置換します。
例2.1 components.xml の注記
faces-config.xml の JSF フェーズリスナー宣言ではなく、components.xml で制御されています。 Seam 管理トランザクションを無効にする場合は次を使用します。
<core:init transaction-management-enabled="false"/>
<core:init transaction-management-enabled="false"/>
event action にある expression 属性は廃止され execute になります。 たとえば、
org.jboss.seam ではなく org.jboss.seam.security> プレフィックスを使用します (例えば org.jboss.seam.security.notLoggedIn)。
注記
org.jboss.seam.postAuthenticate イベントの代わりに、 org.jboss.seam.security.loginSuccessful イベントを使ってキャプチャしたビューに戻ります。
2.1.4. Embedded JBoss への移行 リンクのコピーリンクがクリップボードにコピーされました!
- Seam の
lib/ディレクトリにあるjar bootstrap/ディレクトリ
embeddded-ejb ディレクトリや jboss-beans.xml など JBoss Embeddable EJB3 関連の参照やアーティファクトはすべて削除します。 (Seam のサンプルを参照として使用できます。)
注記
-ds.xml ファイルからブートストラップできるため、 jboss-beans.xml ファイルは必要なくなりました。
2.1.5. jBPM 3.2 への移行 リンクのコピーリンクがクリップボードにコピーされました!
tx サービスを jbpm.cfg.xml に追加する必要があります。
<service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
<service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
2.1.6. RichFaces 3.1 への移行 リンクのコピーリンクがクリップボードにコピーされました!
ajax4jsf.jar と richfaces.jar の jar は richfaces-api.jar (EAR の lib/ ディレクトリに配置される)、 richfaces-impl.jar および richfaces-ui.jar (WEB-INF/lib に配置される) で置き換えられました。
<s:selectDate> は廃止され <rich:calendar> になります。 <s:selectDate> の開発は行われなくなります。 ご使用のスタイルシートからデータピッカー関連のスタイルを削除してバンド幅の使用を減らします。
2.1.7. コンポーネントにおける変更点 リンクのコピーリンクがクリップボードにコピーされました!
application.xml でモジュールとしてこれまで宣言されていた依存性は、jboss-seam.jar を 除き すべて EAR の lib/ ディレクトリに配置されるようになるはずです。 jboss-seam.jar は EJB モジュールとして application.xml に宣言されるはずです。
<s:decorate> は命名コンテナになりました。 したがってクライアント ID は fooForm:fooInput から fooForm:foo:fooInput に変更になり、 次の宣言を前提としています。
<h:form id="fooForm">
<s:decorate id="foo">
<h:inputText id="fooInput" value="#{bean.property}"/>
</s:decorate>
</h:form>
<h:form id="fooForm">
<s:decorate id="foo">
<h:inputText id="fooInput" value="#{bean.property}"/>
</s:decorate>
</h:form>
<s:decorate> に与えないと JSF は ID を自動的に生成します。
Seam 2.0.0.CR2 からは、 generate-entities が実行されるときに seam-gen で生成されたクラスの編成に変更が発生しました。
src/model/com/domain/projectname/model/EntityName.java
src/action/com/domain/projectname/model/EntityNameHome.java
src/action/com/domain/projectname/model/EntityNameList.java
src/model/com/domain/projectname/model/EntityName.java
src/action/com/domain/projectname/model/EntityNameHome.java
src/action/com/domain/projectname/model/EntityNameList.java
src/model/com/domain/projectname/model/EntityName.java
src/action/com/domain/projectname/action/EntityNameHome.java
src/action/com/domain/projectname/action/EntityNameList.java
src/model/com/domain/projectname/model/EntityName.java
src/action/com/domain/projectname/action/EntityNameHome.java
src/action/com/domain/projectname/action/EntityNameList.java
action パッケージに配置されます。 これにより generate-entities 対話が new-entity コマンドのそれと整合性を持ちます。
build.xml ファイルを新しいプロジェクトのベースとして使用することをお勧めします。 build.xml に大幅な変更を行っている場合は、テスト関連の対象のみの移行に焦点を絞ることが可能です。
resources/META-INF/persistence-test.xml (または persistence-test-war.xml) の <datasource> エレメントの値を java:/DefaultDS に変更する必要があります。 代わりに -ds.xml ファイルを bootstrap/deploy フォルダにデプロイして、そのファイルで定義される JNDI 名を使用する方法もあります。
build.xml を使用する場合は deployed-*.list ファイルも必要になります。 これらのファイルは EAR または WAR アーカイブにパッケージ化される jar ファイル群を指定します。 build.xml ファイルから jar セットを取り除くために導入されました。
generate-entities で作成されるすべてのページで 検索基準 ブロックが 結果表 に流出することになります。
.rich-stglpanel-body {
overflow: auto;
}
.rich-stglpanel-body {
overflow: auto;
}
2.2. Seam 2.0 から Seam 2.1 または 2.2 への移行 リンクのコピーリンクがクリップボードにコピーされました!
2.2.1. 依存 jar の名前における変更点 リンクのコピーリンクがクリップボードにコピーされました!
| ファイル名 | 詳細 |
|---|---|
ant-launcher.jar
| |
common-codec.jar
| |
commons-httpclient.jar
| |
concurrent.jar
| |
darkX.jar
|
新しいプラグ可能な RichFaces スキン DarkX
|
drools-api.jar
|
Drools 5 API
|
drools-decisiontables.jar
|
Drools 5 ディシジョンルールの機能
|
drools-templates.jar
|
Drools 5 ルールテンプレートの機能
|
ehcache.jar
| |
glassX.jar
|
新しいプラグ可能な RichFaces スキン GlassX
|
hibernate-core.jar
| |
htmlparser.jar
|
HTML パーサー、OpenID 機能の依存性
|
httpclient.jar
| |
httpcore.jar
| |
itext-rtf.jar
|
itext から RTF にエクスポートするときの拡張オプションの依存性
|
jaxrs-api.jar
| |
jbosscache-core.jar
| |
jboss-common-core.jar
| |
jboss-logging.spi.jar
| |
jboss-seam-excel.jar
|
Microsoft Excel 統合モジュール
|
jboss-seam-resteasy.jar
|
RestEasy 統合モジュール
|
jboss-transaction-api.jar
| |
jboss-vfs.jar
| |
jcip-annotations.jar
| |
jcl-over-slf4j.jar
|
レイテンシロギング API のブリッジ、Resteasy 統合モジュールの依存性
|
jettison.jar
| |
jms.jar
| |
joda-time.jar
| |
junit.jar
| |
jxl.jar
|
Microsoft Excel 統合モジュールの依存性
|
laguna.jar
|
新しいプラグ可能な RichFaces スキン laguna
|
mvel2.jar
|
Drools 5 向けの式言語の依存性
|
openid4java.jar
|
Security Seam モジュールでの統合のための OpenID Java API
|
openxri-client.jar
|
OpenRXI resolver、OpenID 統合の依存性
|
openrxi-syntax.jar
|
OpenXRI パーサー、OpenID 統合の依存性
|
resteasy-atom-provider.jar
|
Resteasy 統合モジュールの依存性
|
resteasy-jaxb-provider.jar
|
Seam の Resteasy 統合モジュールの依存性
|
resteasy-jaxrs.jar
|
Resteasy 統合モジュールの依存性
|
resteasy-jettison-provider.jar
| |
slf4j-api.jar
|
Hibernate および他の依存関係が使用する log4j のロギングブリッジ
|
slf4j-log4j12.jar
|
Hibernate および他の依存関係が使用する log4j のロギングブリッジ
|
testng-jdk15.jar
|
TestNG フレームワーク
|
| JAR | 削除の理由 |
|---|---|
activation.jar
|
アクティブ化は Java 6 に組み込まれているため、ディストリビューションから削除できます。
|
commons-lang.jar
|
Commons Lang ライブラリは必要でなくなりました。
|
geronimo-jms_1.1_spec.jar
| |
geronimo-jtaB_spec-1.0.1.jar
| |
hibernate3.jar
| |
jboss-cache-jdk50.jar
| |
jboss-jmx.jar
| |
jboss-system.jar
| |
mvel.jar
| |
testng.jar
| |
2.2.2. コンポーネントにおける変更点 リンクのコピーリンクがクリップボードにコピーされました!
SeamTest は各クラスの起動時ではなく各スィートの起動時に Seam を起動するようになり、速度が向上します。 デフォルトを変更したい場合はリファレンスガイドをご確認ください。
Seam XML ファイルの Document Type Declarations (DTD) には対応しなくなります。 検証には代わりに XML Schema Declaration (XSD) を使用してください。 Seam 2.0 XSD を使用するファイルはすべて Seam 2.1 XSD を参照するよう更新が必要です。
キャッチされた例外が #{org.jboss.seam.caughtException} として EL で見ることができます。 #{org.jboss.seam.exception} 形式ではなくなります。
entity-loader コンポーネントから使用されるエンティティマネージャを設定できるようになりました。 詳細についてはドキュメントをご覧ください。
Seam Application Framework など Seam のいくつかの部分は Seam 管理永続コンテキスト (JPA) と Hibernate Session 間での共通命名規則の存在に依存しています。 Seam 2.1 以前のバージョンでは管理 Hibernate Session の名前は session になるとみなされていました。session は Seam や Java Servlet API で過剰使用されているため、 デフォルトを hibernateSession に変更することで曖昧性を軽減しました。 つまり、 Hibernate Session のインジェクトまたはリゾルブを行う場合に適切なセッションの識別が非常に容易になります。
@In private Session hibernateSession;
@In private Session hibernateSession;
@In(name = "hibernateSession") private Session session;
@In(name = "hibernateSession") private Session session;
session という名前の場合は、 session プロパティで明示的に参照をインジェクトできます。
<framework:hibernate-entity-home session="#{session}".../>
<transaction:entity-transaction session="#{session}".../>
<framework:hibernate-entity-home session="#{session}".../>
<transaction:entity-transaction session="#{session}".../>
getPersistenceContextName() メソッドを無効化することもできます。
public String getPersistenceContextName() {
"session";
}
public String getPersistenceContextName() {
"session";
}
components.xml にあるセキュリティルールに関する構成がルールベースのセキュリティを使用するプロジェクトに対して変更されました。 以前は、ルールは identity コンポーネントのプロパティとして設定されていました。
<security:identity security-rules="#{securityRules}"
authenticate-method="#{authenticator.authenticate}"/>
<security:identity security-rules="#{securityRules}"
authenticate-method="#{authenticator.authenticate}"/>
ruleBasedPermissionResolver コンポーネントをそのルールベースのパーミッションチェックに使用します。このコンポーネントをアクティブにして identity コンポーネントの代わりにこのコンポーネントでセキュリティルールを登録する必要があります。
<security:rule-based-permission-resolver
security-rules="#{securityRules}"/>
<security:rule-based-permission-resolver
security-rules="#{securityRules}"/>
重要
- 名前
- 動作
- コンテキスト依存のオブジェクト (オプション)
s:hasPermission('userManager', 'edit', user)
s:hasPermission('userManager', 'edit', user)
- ターゲット
- 動作
s:hasPermission(user, 'edit')
s:hasPermission(user, 'edit')
s:hasPermission('userManager', 'edit', user)
s:hasPermission('userManager', 'edit', user)
s:hasPemrission(user, 'edit')
s:hasPemrission(user, 'edit')
このメソッドは資格情報が設定されている場合は認証チェックの試行を行わなくなります。代わりに、 ユーザーが現在未認証の場合は true を返します。 以前の動作を利用する場合は Identity.tryLogin() を使用します。
components.xml に追加してアプリケーションが初めてアクセスされたときにユーザーが自動的にログインされるようにします。
documentStore コンポーネントは外部の pdf/itext モジュールから Seam 自体に移動されました。そのため components.xml にある pdf:document-store への参照はすべて document:document-store で置換されるはずです。 同様に、 web.xml が org.jboss.seam.pdf.DocumentStoreServlet を参照する場合には、その参照を org.jboss.seam.document.DocumentStoreServlet に変更してください。
Seam の ManagedEntityInterceptor (以前は ManagedEntityIdentityInterceptor) はデフォルトでは無効です。クラスタ対話のフェールオーバーに ManagedEntityInterceptor が必要な場合、 次のようにして components.xml で有効できます。
非同期の呼び出しはすべて例外処理でラップされます。 デフォルトでは非同期の呼び出しから伝播する例外はすべてエラーレベルでキャッチされログ記録されます。 詳細は 21章非同期性とメッセージング を参照してください。
org.jboss.seam.postInitialization イベントは再デプロイメント時に呼び出されなくなりました。 代わりに org.jboss.seam.postReInitialization が呼び出されます。
Seam でのキャッシュへの対応は JBoss Cache 3.2、JBoss Cache 2、Ehcache に対応するよう記述し直されました。詳細は 22章キャッシュ を参照してください。
<s:cache /> には変更はありませんが、pojoCache コンポーネントはインジェクトできなくなりました。
CacheProvider はマップのようなインターフェースを提供します。 getDelegate() メソッドを使って基礎となるキャッシュを取得できます。
提供されているプラットフォームは JBoss AS 5.1.0 であるため、javaassist:javaassist と dom4j:dom4j は provided とマークされています。
いくつかのプロパティが値式を予期するようになりました。
entityHome.createdMessageentityHome.updatedMessageentityHome.deletedMessageentityQuery.restrictions
components.xml で設定すると変更は必要ありません。オブジェクトを JavaScript で設定する場合は、値式を次のように作成する必要があります。
public ValueExpression getCreatedMessage() {
return createValueExpression("New person #{person.firstName}
#{person.lastName} created");
}
public ValueExpression getCreatedMessage() {
return createValueExpression("New person #{person.firstName}
#{person.lastName} created");
}
第3章 seam-gen を使った Seam の紹介 リンクのコピーリンクがクリップボードにコピーされました!
3.1. 始める前に リンクのコピーリンクがクリップボードにコピーされました!
WAR と EAR のホット再デプロイメントに対して高度なサポートを提供します。残念ながら、JVM のバグのため EAR の再デプロイメントを繰り返すと (開発段階では一般的)、JVM の perm gen 領域を使い果たすことになります。このため、開発段階では大規模な perm gen 領域を持つ JVM で JBoss を稼動させることが推奨されます。 JBoss IDE から JBoss を稼動させる場合は、「VM arguments」の下にあるサーバ起動設定でこれを設定することができます。以下の値が推奨されます。
-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m
-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m
-Xms256m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=256m
-Xms256m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=256m
bin/run.conf の JVM オプションを設定することが可能です。
3.2. 新しいプロジェクトの設定 リンクのコピーリンクがクリップボードにコピーされました!
cd seam_distribution_dir; seam setup
EAR または WAR アーカイブとして行うかどうかということです。EAR プロジェクトは Enterprise JavaBeans 3.0 (EJB3) に対応しており、Java EE 5 が必要です。WAR プロジェクトは EJB3 に対応していませんが、J2EE 環境にデプロイ可能です。WAR は EAR に比べシンプルなパッケージです。JBoss のような EJB3 に対応済みのアプリケーションサーバーがインストールされている場合は ear を選択してください。これ以外は war を選択してください。以降、このチュートリアルでは EAR デプロイメントを使用していると仮定しますが、プロジェクトが WAR デプロイメントの場合もこのステップに沿って進めることができます。
seam new-project を入力して、Eclipse ワークスペースディレクトリに新しいプロジェクトを作成します。
JAR 郡、依存する JAR 郡、 JDBC ドライバの JAR 郡を新しい Eclipse プロジェクトにコピーします。 必要となるすべてのリソースや設定ファイル、 Facelets テンプレートファイルとスタイルシートの他、 Eclipse メタデータと Ant ビルドスクリプトを生成します。 プロジェクトを追加すると直ちに Eclipse プロジェクトは JBoss 内の展開されたディレクトリ構造に自動的にデプロイされます。 プロジェクトを追加するには、 → → → → の順で進み、 Project name (この場合は helloworld) を入力し Finish をクリックします。New Project のウィザードで Java Project は選択しないようにしてください。
seam explode と入力し Eclise の外部からプロジェクトをデプロイすることもできます。
http://localhost:8080/helloworld にあります。これは view/layout/template.xhtml にあるテンプレートを使って作成された Facelets のページ (view/home.xhtml) です。 Eclipse からこのページやテンプレートの編集が可能です。 ブラウザを更新すると結果をすぐに見ることもできます。
persistence-test.xml と import-test.sql ファイルが使用されます。 import-test.sql のデータベーススキーマとテストデータは常にテストが実行される前にデータベースにエキスポートされます。 myproject-dev-ds.xml、 persistence-dev.xml、 import-dev.sql はアプリケーションを開発データベースにデプロイするときに使用します。 seam-gen に既存データベースで作業していることを認識させている場合は、 デプロイ時にスキーマが自動的にエクスポートされる場合があります。 myproject-prod-ds.xml、 persistence-prod.xml と import-prod.sql は実稼働用のデータベースにアプリケーションをデプロイするときに使用します。 スキーマはデプロイ時に自動的にはエクスポートされません。
3.3. 新しいアクションの作成 リンクのコピーリンクがクリップボードにコピーされました!
seam new-action を入力するとステートレスなアクションメソッドを持つシンプルな Web ページを作成することができます。
seam restart と入力するか、 Eclipse 内から生成されたプロジェクトの build.xml ファイルの restart ターゲットを実行します。別の方法として、 Eclipse の resources/META-INF/application.xml ファイルを編集することでも可能です。
注記
http://localhost:8080/helloworld/ping.seam に移動し、ボタンをクリックします。 プロジェクトの src ディレクトリを見れば、 このアクションの背後のコードを見ることができます。 ping() メソッドにブレークポイントを追加し、 再度ボタンをクリックします。
PingTest.xml ファイルを探し Eclipse 用の TestNG プラグインを使用して統合テストを実行します。 また、 seam test や生成されたビルドの test ターゲットを使ってテストを実行することも可能です。
3.4. アクションのあるフォームの作成 リンクのコピーリンクがクリップボードにコピーされました!
seam new-form を入力します。
http://localhost:8080/helloworld/hello.seam に移動します。 生成されたコードを見てみましょう。 テストを実行します。フォームと Seam コンポーネントに新しいフィールドを追加してみてください (Java コードを変更したら常にデプロイメントを再実行することを忘れないようにしてください)。
3.5. 既存のデータベースからのアプリケーションの生成 リンクのコピーリンクがクリップボードにコピーされました!
seam setup を実行します)。ここで seam generate-entities を入力します。
http://localhost:8080/helloworld に移動します。 データベースの閲覧、 既存オブジェクトの編集、 新しいオブジェクトの作成が可能です。 生成されたコードは非常にシンプルです。Seam は seam-gen がなくても手作業でデータアクセスコードを簡単に書けるよう設計されているからです。
3.6. 既存の JPA/EJB3 エンティティからのアプリケーションの生成 リンクのコピーリンクがクリップボードにコピーされました!
src/main ディレクトリの内側に配置します。ここで seam generate-ui を入力します。
http://localhost:8080/helloworld に移動します。
3.7. EAR 形式でのアプリケーションのデプロイ リンクのコピーリンクがクリップボードにコピーされました!
seam unexplode を実行して展開したディレクトリを削除します。 EAR をデプロイするには、 コマンドプロンプトで seam deploy を入力するか、 生成されたプロジェクトのビルドスクリプトの deploy ターゲットを実行します。 デプロイ解除するには、 seam undeploy または undeploy ターゲットを使用します。
persistence-dev.xml ファイルと import-dev.sql ファイルを含み、myproject-dev-ds.xml をデプロイします。seam -Dprofile=prod deploy を入力して、プロファイルを prod profile に変更できます。
persistence-staging.xml、 import-staging.sql、 myproject-staging-ds.xml です。 -Dprofile=staging を使ってプロファイルの名前を選択します。
3.8. Seam と増分ホットデプロイメント リンクのコピーリンクがクリップボードにコピーされました!
components.xml に追加して Seam と Facelets でデバッグモードを有効にします。
<core:init debug="true">
<core:init debug="true">
警告
- Facelets のすべてのページ
- すべての
pages.xmlファイル
application.xml、WAR デプロイメントでは web.xml です。
WEB-INF/dev ディレクトリにデプロイする必要があります。これで、JavaBean コンポーネントは WAR あるいは EAR クラスローダの代わりに特別な Seam クラスローダによってロードされます。
- コンポーネントは JavaBean コンポーネントでなければなりません。 EJB3 Bean コンポーネントは使用できません (この制約は修正中です)。
- エンティティはホットデプロイされることはありません。
components.xmlでデプロイされたコンポーネントはホットデプロイできない場合があります。- ホットデプロイ可能なコンポーネントは、
WEB-INF/devの外部にデプロイされたクラスからは見えません。 - Seam デバッグモードを有効にして
jboss-seam-debug.jarをWEB-INF/libに配置する必要があります。 web.xmlに Seam フィルタをインストールしなければなりません。- システムに負荷がかかりデバッグが有効な場合は、エラーが表示されることがあります。
src/hot ソースディレクトリにあるクラスに対してはそのまま増分ホットデプロイメントが使用可能です。 ただし、 seam-gen は EAR プロジェクトの増分ホットデプロイには対応していません。
第4章 JBoss Developer Studio を使って Seam を始めよう リンクのコピーリンクがクリップボードにコピーされました!
4.1. 始める前に リンクのコピーリンクがクリップボードにコピーされました!
4.2. 新しい Seam プロジェクトの設定 リンクのコピーリンクがクリップボードにコピーされました!
helloworld を使用します。
-Xms256m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=256
-Xms256m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=256
4.3. 新しいアクションの作成 リンクのコピーリンクがクリップボードにコピーされました!
http://localhost:8080/helloworld/ping.seam に移動し、ボタンをクリックします。 プロジェクトの src ディレクトリでこのアクションの背後のコードを見ることができます。ping() メソッドにブレークポイントを追加し、再度ボタンをクリックします。
helloworld-test プロジェクトを開き PingTest クラスを探し右クリックします。 Run As -> TestNG Test の順に選択します。
4.4. アクションのあるフォームの作成 リンクのコピーリンクがクリップボードにコピーされました!
http://localhost:8080/helloworld/hello.seam に移動し、生成されたコードを見てみましょう。テストを実行します。フォームと Seam コンポーネントに新しいフィールドを追加してみてください。Seam がコンポーネントをホットリロードするため、src/action コードを変更するたびにアプリケーションサーバーを再起動する必要はありません。
4.5. 既存のデータベースからのアプリケーションの生成 リンクのコピーリンクがクリップボードにコピーされました!
http://localhost:8080/helloworld に移動します。データベースの閲覧、既存オブジェクトの編集、新規オブジェクトの作成が可能です。生成されたコードは非常にシンプルです。Seam では手作業で簡単にデータアクセスコードが書けるよう設計されています。リバースエンジニアリングも不要です。
4.6. JBoss Developer Studio を使った Seam と増分ホットデプロイメント リンクのコピーリンクがクリップボードにコピーされました!
pages.xml ファイルの増分ホットデプロイメントに対応しています。ただし、Java コードを変更したい場合は Full Publish を行うことで、アプリケーションを完全に再起動する必要があります。
WEB-INF/dev ディレクトリにデプロイする必要があります。これで、JavaBean コンポーネントは WAR または EAR クラスローダの代わりに特別な Seam クラスローダによってロードされます。
- コンポーネントは JavaBean コンポーネントでなければなりません。 EJB3 Bean コンポーネントは使用できません (この制約は修正中です)。
- エンティティはホットデプロイされることはありません。
components.xmlでデプロイされたコンポーネントはホットデプロイできない場合があります。- ホットデプロイ可能なコンポーネントは
WEB-INF/devの外部にデプロイされたクラスからは見えません。 - Seam デバッグモードを有効にして
jboss-seam-debug.jarをWEB-INF/libに配置する必要があります。 web.xmlに Seam フィルタをインストールしなければなりません。- システムに負荷がかかりデバッグが有効な場合は、エラーが表示されることがあります。
第5章 コンテキスト依存のコンポーネントモデル リンクのコピーリンクがクリップボードにコピーされました!
5.1. Seam コンテキスト リンクのコピーリンクがクリップボードにコピーされました!
- ステートレスなコンテキスト
- イベント (例えば 要求) のコンテキスト
- ページのコンテキスト
- 対話のコンテキスト
- セッションのコンテキスト
- ビジネスプロセスのコンテキスト
- アプリケーションのコンテキスト
5.1.1. ステートレスなコンテキスト リンクのコピーリンクがクリップボードにコピーされました!
5.1.2. イベントのコンテキスト リンクのコピーリンクがクリップボードにコピーされました!
5.1.3. ページのコンテキスト リンクのコピーリンクがクリップボードにコピーされました!
5.1.4. 対話のコンテキスト リンクのコピーリンクがクリップボードにコピーされました!
5.1.5. セッションのコンテキスト リンクのコピーリンクがクリップボードにコピーされました!
5.1.6. ビジネスプロセスのコンテキスト リンクのコピーリンクがクリップボードにコピーされました!
5.1.7. アプリケーションのコンテキスト リンクのコピーリンクがクリップボードにコピーされました!
5.1.8. コンテキスト変数 リンクのコピーリンクがクリップボードにコピーされました!
Contexts クラスで特定のスコープ内の名前付きコンポーネントインスタンスにプログラム的にアクセスすることができ、これにより Context インターフェースのスレッドに結びついた複数のインスタンスへのアクセスを提供します。
User user = (User) Contexts.getSessionContext().get("user");
User user = (User) Contexts.getSessionContext().get("user");
Contexts.getSessionContext().set("user", user);
Contexts.getSessionContext().set("user", user);
5.1.9. コンテキストの検索優先順位 リンクのコピーリンクがクリップボードにコピーされました!
- イベントのコンテキスト
- ページのコンテキスト
- 対話のコンテキスト
- セッションのコンテキスト
- ビジネスプロセスのコンテキスト
- アプリケーションのコンテキスト
Contexts.lookupInStatefulContexts() を呼び出すことで優先順位の検索を行うことができます。 JSF ページから名前でコンポーネントにアクセスする場合は常に優先順位検索が発生します。
5.1.10. 同時実行モデル リンクのコピーリンクがクリップボードにコピーされました!
@Synchronized アノテーションを追加することで、あらゆるセッション Bean や JavaBean コンポーネントに強制できます。
5.2. Seam コンポーネント リンクのコピーリンクがクリップボードにコピーされました!
- EJB3 ステートレスセッション Bean
- EJB3 ステートフルセッション Bean
- EJB3 エンティティ Bean (JPA エンティティクラスなど)
- JavaBeans
- EJB3 メッセージ駆動型 Bean
- Spring Bean (26章Spring Framework 統合 を参照)
5.2.1. ステートレスセッション Bean リンクのコピーリンクがクリップボードにコピーされました!
Component.getInstance() または @In(create=true) のいずれかを使用してインスタンス化されます。 JNDI 検索や new 演算子で直接インスタンス化しないでください。
5.2.2. ステートフルセッション Bean リンクのコピーリンクがクリップボードにコピーされました!
HttpSession ではなく対話コンテキストにバインドされたステートフルセッション Bean のインスタンス変数内に格納します。 これにより、 Seam が状態のライフサイクルを管理し、 異なる同時の対話に関する状態間で衝突が起こらないようにします。
Component.getInstance() または @In(create=true) のいずれかを使用してインスタンス化されます。 JNDI 検索や new 演算子で直接インスタンス化を行わないでください。
5.2.3. エンティティ Bean リンクのコピーリンクがクリップボードにコピーされました!
注記
Component.getInstance() または @In(create=true) のいずれかを使用してインスタンス化されるか、 new 演算子を使用して直接インスタンス化されます。
5.2.4. JavaBeans リンクのコピーリンクがクリップボードにコピーされました!
注記
Component.getInstance() または @In(create=true) のいずれかを使用してインスタンス化されます。 new 演算子で直接インスタンス化しないでください。
5.2.5. メッセージ駆動型 Bean リンクのコピーリンクがクリップボードにコピーされました!
5.2.6. インターセプション リンクのコピーリンクがクリップボードにコピーされました!
@Stateless
@Interceptors(SeamInterceptor.class)
public class LoginAction implements Login { ... }
@Stateless
@Interceptors(SeamInterceptor.class)
public class LoginAction implements Login { ... }
ejb-jar.xml もインターセプタを定義する方がよいでしょう。
5.2.7. コンポーネント名 リンクのコピーリンクがクリップボードにコピーされました!
@Name アノテーションを使用してコンポーネントに名前を割り当てます。
@Name("loginAction")
@Stateless
public class LoginAction implements Login { ... }
@Name("loginAction")
@Stateless
public class LoginAction implements Login { ... }
@Name だけがコンポーネント名を定義する唯一の方法ではありませんが、 この名前は常に指定しなければなりません。 名前が定義されていないと他の Seam アノテーションが機能しません。
User を currentUser セッションコンテキスト変数にバインドする一方、管理機能の対象となる User も user 対話コンテキスト変数にバインドすることがあります。 Seam コンポーネントを参照するコンテキスト変数を上書きすることは可能なため、プログラムによってバインドを行う場合は注意してください。
@Name("com.jboss.myapp.loginAction")
@Stateless
public class LoginAction implements Login { ... }
@Name("com.jboss.myapp.loginAction")
@Stateless
public class LoginAction implements Login { ... }
<h:commandButton type="submit" value="Login"
action="#{com.jboss.myapp.loginAction.login}"/>
<h:commandButton type="submit" value="Login"
action="#{com.jboss.myapp.loginAction.login}"/>
components.xml ファイルに追加します。
<factory name="loginAction" scope="STATELESS"
value="#{com.jboss.myapp.loginAction}"/>
<factory name="loginAction" scope="STATELESS"
value="#{com.jboss.myapp.loginAction}"/>
components.xml ファイルは以下の名前空間を定義します。
components.xml ファイルに含めることができます。
5.2.8. コンポーネントスコープの定義 リンクのコピーリンクがクリップボードにコピーされました!
@Scope アノテーションを使用してコンポーネントのスコープ (コンテキスト) を上書きし、 Seam によるインスタンス化のときにコンポーネントインスタンスがバインドされるコンテキストを定義することができます。
@Name("user")
@Entity
@Scope(SESSION)
public class User { ... }
@Name("user")
@Entity
@Scope(SESSION)
public class User { ... }
org.jboss.seam.ScopeType は可能なスコープの列挙を定義します。
5.2.9. 複数のロールを持つコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
User クラスは通常現在のユーザーを表すセッションスコープのコンポーネントですが、 ユーザー管理画面では対話スコープのコンポーネントになります。 @Role アノテーションを使用すると、 1 つのコンポーネントに異なるスコープで追加の名前が付いたロールを定義することができます。 これにより、 同じコンポーネントクラスを別のコンテキスト変数にバインドさせることができます (いずれの Seam コンポーネントの インスタンス も複数のコンテキスト変数にバインド可能ですが、 クラスレベルで行えるため自動インスタンス化を利用することができます)。
@Name("user")
@Entity
@Scope(CONVERSATION)
@Role(name="currentUser", scope=SESSION)
public class User { ... }
@Name("user")
@Entity
@Scope(CONVERSATION)
@Role(name="currentUser", scope=SESSION)
public class User { ... }
@Roles アノテーションは必要に応じてロールを追加で指定することができます。
5.2.10. 組み込みコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.core および同じ名前の Java パッケージで定義されます。
instance() という便利で静的なメソッドも提供しています。
FacesMessages.instance().add("Welcome back, #{user.name}!");
FacesMessages.instance().add("Welcome back, #{user.name}!");
5.3. バイジェクション リンクのコピーリンクがクリップボードにコピーされました!
- コンテキスト依存
- バイジェクションは各種のコンテキストからステートフルなコンポーネントを組み立てるために使用されます。 より広い コンテキストからのコンポーネントは より狭い コンテキストからのコンポーネントへの参照を行うこともできます。
- 双方向的
- 値はコンテキスト変数から呼び出されたコンポーネントの属性にインジェクトされ、コンテキストに戻されます (アウトジェクション)。 これによりそれ自体のインスタンス変数を設定するだけで、呼び出されたコンポーネントはコンテキスト依存の変数の値を操作することができます。
- 動的
- コンテキスト依存の変数の値は時間経過で変化し、 Seam のコンポーネントはステートフルであるため、 バイジェクションはコンポーネントが呼び出されるたびに発生します。
@In アノテーションは値がインスタンス変数または setter メソッドにインジェクトされることを指定します。 インスタンス変数の場合、
@In("currentUser") を使って明示的にコンテキスト変数名を指定したいと思われるかもしれません。
@In(create=true) を指定します。 値がオプションで (null でも可能) あれば @In(required=false) を指定します。
@In(create=true) を指定することは同じ動作の繰り返しとなる場合があります。 このような場合、 コンポーネントに @AutoCreate アノテーションを付与します。 これにより create=true を明示的に使用しなくても必要なときに常に作成されるようになります。
null に設定されます)。
@Outアノテーションは属性がインスタンス変数または getter メソッドのいずれかからアウトジェクトされることを指定します。 インスタンス変数の場合、
5.4. ライフサイクルのメソッド リンクのコピーリンクがクリップボードにコピーされました!
@PostConstruct、 @PreDestroy など) をサポートしていますが、 Seam は JavaBean コンポーネントでのこれらコールバックの使用もサポートします。 ただし、 これらのアノテーションは J2EE 環境では有効とならないため Seam は @PostConstruct と @PreDestroy と等価な 2 つの追加コンポーネントライフサイクルのコールバックを定義します。
@Create メソッドは Seam がコンポーネントをインスタンス化した後に呼び出されます。 コンポーネントが定義できるのは 1 つの @Createメソッドのみになります。
@Destroy メソッドは Seam コンポーネントがバインドするコンテキストが終了すると呼び出されます。 コンポーネントが定義できるのは 1 つの @Destroy メソッドのみです。
@Remove アノテーションが付いたパラメータのないメソッドをひとつ定義 しなければなりません。 このメソッドはコンテキストが終了すると Seam により呼び出されます。
@Startup アノテーションはいずれのアプリケーションまたはセッションスコープのコンポーネントにも適用することができます。 @Startup アノテーションは、 クライアントによって参照されるのを待たずにコンテキストが開始したら直ちに Seam にコンポーネントをインスタンス化するよう指示します。 @Startup(depends={....}) を指定するとスタートアップコンポーネントをインスタンス化する順序を制御することができます。
5.5. 条件付きインストール リンクのコピーリンクがクリップボードにコピーされました!
@Install アノテーションは、特定のデプロイメントシナリオでは必要とされるがそれ以外では必要とされないコンポーネントの条件付きインストールを制御します。これは以下の場合に役立ちます。
- 試験的に基盤となる模擬コンポーネントを作成する
- 特定のデプロイメントシナリオでコンポーネント実装を変更する、または
- コンポーネントの依存部分が利用可能な場合に、 そのコンポーネントをインストールする (フレームワークの作成者に便利)。
@Install で 優先順位 と 依存性 を指定することができます。
BUILT_IN− 最も優先順位が低いコンポーネントは Seam に組み込まれたコンポーネントです。FRAMEWORK− サードパーティのフレームワークによって定義されたコンポーネントは組み込みコンポーネントより優先させることができますが、 アプリケーションコンポーネントにより優先されます。APPLICATION− デフォルトの優先順位です。ほとんどのアプリケーションコンポーネントにはこれが適切です。DEPLOYMENT− デプロイメント固有のアプリケーションコンポーネント用です。MOCK− テストで使用されるモックオブジェクト用です。
messageSender という名前のコンポーネントがあるとします。
precedence はクラスパスで両方のコンポーネントを発見したときに Seam が使用するバージョンを決定するときに役立ちます。
jar 全体に渡りそのフレームワークを分散させたいとは思わないでしょう。 インストール済みの別のコンポーネントやクラスパスにある使用可能なクラスに応じてインストールするコンポーネントを決定する方が好まれるはずです。 @Install アノテーションはこの機能も制御します。Seam は多くの組み込みコンポーネントの条件付きインストールを実現するために内部でこのメカニズムを使用します。
5.6. ロギング リンクのコピーリンクがクリップボードにコピーされました!
log 変数を静的に宣言したかどうかに関係なく、 エンティティ Bean コンポーネント (log 変数が静的でなければならない) 以外ならいずれでも動作します。
debug() メソッド内部で起こるため、 冗長な if ( log.isDebugEnabled() ) による保護は不要です。 Seam は log のインジェクト先を認識できるため、 通常はログカテゴリを明示的に指定する必要もありません。
User と Product が現在のコンテキストで有効な Seam コンポーネントならコードはさらに簡潔になります。
5.7. Mutable インターフェースと @ReadOnly リンクのコピーリンクがクリップボードにコピーされました!
HttpSession のクラスタリングを備えており、setAttribute 明示的に呼び出された場合にのみ、セッションにバインドした可変のオブジェクトの状態への変化が複製されます。これはフェールオーバーが発生する場合にのみ出現するバグを招く可能性があり、 開発時に効果的なテストを行うことができません。 さらに、 複製メッセージ自体はセッション属性にバインドしたシリアライズされたオブジェクトグラフ全体を含むため効率的ではありません。
setAttribute() を呼び出して自動的に複製を強制します。 ただし、 この方法は read-mostly コンポーネントには役立ちません。 org.jboss.seam.core.Mutable インターフェースを実装、または org.jboss.seam.core.AbstractMutable を拡張して、 コンポーネントの中に独自のダーティチェックのロジックを記述しこの動作を制御します。 以下に例を示します。
@ReadOnly アノテーションを使用することもできます。
setAttribute() を呼び出して自動的に複製を強制します。 この方法は必ずしも効率的とは限らないので、 セッションや対話スコープのエンティティ Bean は注意して使用してください。 エンティティ Bean インスタンスの「管理」にはステートフルセッション Bean や JavaBean コンポーネントをいつでも記述することができます。 以下に例を示します。
EntityHome クラスは Seam コンポーネントを使ったエンティティ Bean インスタンスの管理に適した例となる点に留意してください。
5.8. ファクトリとマネージャのコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
@In を使用して Seam コンポーネントにインジェクトし、値メソッドバインディング式およびメソッドバインディング式でそれらを使用して Seam コンテキストのライフサイクルに関連付けたい場合があります (例えば @Destroy など)。 このため、 Seam コンテキストは Seam コンポーネントではないオブジェクトを保持することができ、 Seam にはコンテキストにバインドする非コンポーネントオブジェクトとの作業を簡略化する機能が複数備わっています。
@Factory アノテーションを使用してファクトリメソッドを定義します。 ファクトリメソッドは値をコンテキスト変数にバインドし、 バインドした値のスコープを決定します。ファクトリメソッドのスタイルは 2 種類あります。 最初のスタイルは Seam によりコンテキストにバインドされる値を返します。
@Factory(scope=CONVERSATION)
public List<Customer> getCustomerList() {
return ... ;
}
@Factory(scope=CONVERSATION)
public List<Customer> getCustomerList() {
return ... ;
}
void タイプのメソッドです。
@DataModel List<Customer> customerList;
@Factory("customerList")
public void initCustomerList() {
customerList = ... ;
}
@DataModel List<Customer> customerList;
@Factory("customerList")
public void initCustomerList() {
customerList = ... ;
}
customerList コンテキスト変数が参照されその値が null になるとファクトリメソッドが呼び出されます。 ファクトリメソッドはその値のライフサイクルではこれ以上何も持っていません。 さらに強力なパターンは マネージャコンポーネントパターン です。 この場合、 コンテキスト変数にバインドする Seam コンポーネントがコンテキスト変数の値を管理し、 残りはクライアントから見えません。
@Unwrap メソッドを持つあらゆるコンポーネントです。 このメソッドはクライアント側から見える値を返し、 コンテキスト変数が参照されるたびに呼び出されます。
@Unwrap してマネージャコンポーネントの @Destroy メソッドでクリーンアップを実行することが可能です。
第6章 Seam コンポーネントの構成 リンクのコピーリンクがクリップボードにコピーされました!
web.xml でのプロパティ設定によるコンポーネントの設定と components.xml によるコンポーネントの設定です。
6.1. プロパティ設定によるコンポーネントの構成 リンクのコピーリンクがクリップボードにコピーされました!
seam.properties プロパティファイルのいずれかを持つ設定プロパティを Seam に与えることができます。
com.jboss.myapp.settings という名前の Seam コンポーネントに setLocale() という setter メソッドがある場合、 次のいずれかを与えることができます。
seam.propertiesファイル内にcom.jboss.myapp.settings.localeという名前のプロパティを与えることができます。- 起動時に
-Dでorg.jboss.seam.properties.com.jboss.myapp.settings.localeという名前のシステムプロパティを与えることができます。 - または、 サーブレットコンテキストパラメータとして同じシステムプロパティを与えることができます。
locale 属性値を設定します。
org.jboss.seam.core.manager.conversationTimeout の値を web.xml または seam.properties 内に与えるか、 org.jboss.seam.properties が先頭に付いたシステムプロパティで与えます。 (setConversationTimeout() という setter メソッドを持つ org.jboss.seam.core.manager という名前の組み込み Seam コンポーネントがあります。)
6.2. components.xml によるコンポーネントの設定 リンクのコピーリンクがクリップボードにコピーされました!
components.xml ファイルはプロパティ設定よりパワフルです。次を行うことができます。
@Nameアノテーションが付けられ、Seam のデプロイメントスキャナーで検出されたアプリケーションコンポーネントや組み込みコンポーネントなど自動的にインストールされているコンポーネントの設定を行います。- Seam コンポーネントとして
@Nameアノテーションが付かないクラスをインストールします。別々の名前で複数回インストールが可能なインフラストラクチャコンポーネントに対して最も役立ちます (たとえば、 Seam 管理永続コンテキストなど)。 @Nameアノテーションは付いているが、そのコンポーネントはインストールしないことを示す@Installアノテーションが付いているためデフォルトではインストールされないコンポーネントをインストールします。- コンポーネントのスコープを無効にします。
components.xml ファイルは次の 3 つの異なる場所のいずれかに置くことができます。
WARのWEB-INFディレクトリJARのMETA-INFディレクトリ@Nameアノテーション付きのクラスを含む任意のJARディレクトリ
@Install アノテーションがない限り、デプロイメントスキャナーが seam.properties ファイルまたは META-INF/components.xml ファイルを持つ @Name アノテーション付きのクラスを見つけた場合、Seam コンポーネントはインストールされます。components.xml ファイルはアノテーションを無効にしなければならない特殊なケースを処理します。
components.xml ファイルは jBPM をインストールします。
<components> <component class="org.jboss.seam.bpm.Jbpm"/> </components>
<components>
<component class="org.jboss.seam.bpm.Jbpm"/>
</components>
auto-create オプションが一般的に使用され、@In アノテーションを使うときに明示的に create=true を指定する必要がありません。
<factory> 宣言は値バインディング式もしくはメソッドバインディング式を指定し、 これが最初に参照されたときにコンテキスト変数の値を初期化します。
<components>
<factory name="contact" method="#{contactManager.loadContact}"
scope="CONVERSATION"/>
</components>
<components>
<factory name="contact" method="#{contactManager.loadContact}"
scope="CONVERSATION"/>
</components>
<components>
<factory name="user" value="#{actor}" scope="STATELESS"/>
</components>
<components>
<factory name="user" value="#{actor}" scope="STATELESS"/>
</components>
<components>
<factory name="contact" value="#{contactManager.contact}"
scope="STATELESS"/>
</components>
<components>
<factory name="contact" value="#{contactManager.contact}"
scope="STATELESS"/>
</components>
auto-create="true" は <factory> 宣言とよく併用されます。
<components>
<factory name="session" value="#{entityManager.delegate}"
scope="STATELESS" auto-create="true"/>
</components>
<components>
<factory name="session" value="#{entityManager.delegate}"
scope="STATELESS" auto-create="true"/>
</components>
components.xml ファイルが使用されることがあります (若干の変更あり)。 Seam は components.xml 内に @wildcard@ 形式のワイルドカードを配置することが可能で、 Ant ビルドスクリプトまたはクラスパスに components.properties というファイルを与えることによって置き換えることができます (2 番目のアプローチを Seam のサンプルで見ることができます)。
6.3. 細分化した構成ファイル リンクのコピーリンクがクリップボードにコピーされました!
components.xml をいくつかの小さいファイルに分割する方が実用的でしょう。 Seam では、 com.helloworld.Hello という名前のクラスの設定は com/helloworld/Hello.component.xml という名前のリソース内に置くことができます (このパターンは Hibernate でも使われています)。このファイルのルートエレメントは <components> または <component> エレメントのいずれかが可能です。
<components> ではこのファイル内に複数のコンポーネントを定義することができます。
<component> では 1 つのコンポーネントしか設定できませんが、 冗長性が抑えられます。
<component name="hello">
<property name="name">#{user.name}</property>
</component>
<component name="hello">
<property name="name">#{user.name}</property>
</component>
com/helloworld/components.xmlで com.helloworld パッケージ内のすべてのクラスの設定をすることも可能です。
6.4. 設定可能なプロパティのタイプ リンクのコピーリンクがクリップボードにコピーされました!
- org.jboss.seam.core.manager.conversationTimeout 60000
- <core:manager conversation-timeout="60000"/>
<component name="org.jboss.seam.core.manager">
<property name="conversationTimeout">60000</property>
</component>
<component name="org.jboss.seam.core.manager">
<property name="conversationTimeout">60000</property>
</component>
org.jboss.seam.bpm.jbpm.processDefinitions order.jpdl.xml, return.jpdl.xml, inventory.jpdl.xml
org.jboss.seam.bpm.jbpm.processDefinitions
order.jpdl.xml,
return.jpdl.xml,
inventory.jpdl.xml
SortedSet/SortedMap が使用されていない限りデフォルトでは components.xml に設定された属性の順序を維持します。 この場合、Seam は TreeMap/TreeSet を参照します。 プロパティに具体的なタイプ (LinkedList など) がある場合はそのタイプを使用します。
@In でのインジェクションとは非常に異なる点に注意してください。 JavaServer Faces (JSF) や Spring などの従来の IoC コンテナによって提供される依存性インジェクションに似ています。
<drools:managed-working-memory name="policyPricingWorkingMemory"
rule-base="#{policyPricingRules}"/>
<drools:managed-working-memory name="policyPricingWorkingMemory"
rule-base="#{policyPricingRules}"/>
<component name="policyPricingWorkingMemory"
class="org.jboss.seam.drools.ManagedWorkingMemory">
<property name="ruleBase">#{policyPricingRules}</property>
</component>
<component name="policyPricingWorkingMemory"
class="org.jboss.seam.drools.ManagedWorkingMemory">
<property name="ruleBase">#{policyPricingRules}</property>
</component>
ValueExpression または MethodExpression のいずれかに割り当てられる場合、 その EL の評価は遅延されて適切な式のラッパーが生成されプロパティに割り当てられます。 Seam Application Framework の Home コンポーネントにあるメッセージテンプレートがその一例です。
ValueExpression または MethodExpression のいずれかで getExpressionString() を呼び出すと式の文字列にアクセスすることができます。 プロパティが ValueExpression となる場合はその値を getValue() で解決します。 プロパティが MethodExpression となる場合は invoke({Object arguments}) でメソッドを呼び出します。 MethodExpression プロパティに値を割り当てるには、 初期値全体がひとつの E L式でなければなりません。
6.5. XML 名前空間の使用 リンクのコピーリンクがクリップボードにコピーされました!
components.xml ファイルを示します。
components.xml ファイルの生成と保守が容易になります。
<component> 宣言を使用できるようにし、 また組み込みコンポーネントには名前空間が付いた宣言が使用できるようにしています。 さらに重要な点は、 Seam により独自のコンポーネントに対して簡単に名前空間を宣言できるということです。
@Namespace アノテーションをパッケージに付加することによって XML 名前空間を関連付けることができます (パッケージレベルのアノテーションはパッケージディレクトリ内の package-info.java という名前のファイルに宣言します)。seampay デモからの例を示します。
@Namespace(value="http://jboss.com/products/seam/examples/ seampay") package org.jboss.seam.example.seampay; import org.jboss.seam.annotations.Namespace;
@Namespace(value="http://jboss.com/products/seam/examples/ seampay") package org.jboss.seam.example.seampay; import org.jboss.seam.annotations.Namespace;
components.xml で名前空間のスタイルを使用するのはこんなに簡単です。 次のように記述できます。
<pay:payment-home> が paymentHome コンポーネントを参照しています。
<pay:payment> エレメントが org.jboss.seam.example.seampay パッケージにある Payment クラスを参照しています。 この場合 Payment は Seam コンポーネントとして宣言されているエンティティです。
- components —
http://jboss.com/products/seam/components - core —
http://jboss.com/products/seam/core - drools —
http://jboss.com/products/seam/drools - framework —
http://jboss.com/products/seam/framework - jms —
http://jboss.com/products/seam/jms - remoting —
http://jboss.com/products/seam/remoting - theme —
http://jboss.com/products/seam/theme - security —
http://jboss.com/products/seam/security - mail —
http://jboss.com/products/seam/mail - web —
http://jboss.com/products/seam/web - pdf —
http://jboss.com/products/seam/pdf - spring —
http://jboss.com/products/seam/spring
第7章 イベント、インターセプタ、例外処理 リンクのコピーリンクがクリップボードにコピーされました!
7.1. Seam イベント リンクのコピーリンクがクリップボードにコピーされました!
- JSF イベント
- jBPM 遷移イベント
- Seam ページアクション
- Seam コンポーネント駆動イベント
- Seam コンテキスト依存イベント
<h:commandButton value="Click me!" action="#{helloWorld.sayHello}"/>
<h:commandButton value="Click me!" action="#{helloWorld.sayHello}"/>
7.2. ページアクション リンクのコピーリンクがクリップボードにコピーされました!
WEB-INF/pages.xml で宣言します。 特定の JSF ビュー ID に対してページアクションを定義することも可能です。
<pages>
<page view-id="/hello.jsp" action="#{helloWorld.sayHello}"/>
</pages>
<pages>
<page view-id="/hello.jsp" action="#{helloWorld.sayHello}"/>
</pages>
view-id へのサフィックスとして * ワイルドカードを使用し、パターンに一致するすべてのビュー ID に適用するアクションを指定します。
<pages>
<page view-id="/hello/*" action="#{helloWorld.sayHello}"/>
</pages>
<pages>
<page view-id="/hello/*" action="#{helloWorld.sayHello}"/>
</pages>
注記
<page> エレメントが細かなページ記述子で定義されている場合は暗黙的に定義されるため view-id 属性を省略することができます。
<page> エレメントに記載されている ビュー ID は実際の JSP や Facelet ページに対応する必要がありません。 このため、 ページアクションを使って Struts や WebWork のような従来のアクション指向のフレームワーク機能を再生することができます。 HTTP GET など Faces 以外の要求への応答に複雑な動作を行う場合に便利です。
<action> タグを使って指定できます。
true に解決する条件を設定します。
ResponseStateManager#isPostback(FacesContext) を参照して要求がポストバックであるかどうかを判断します。 ResponseStateManager には FacesContext.getCurrentInstance().getRenderKit(). getResponseStateManager() を使ってアクセスします。
on-postback 属性を false に設定するとポストバックでページアクションを無効にすることができます。
on-postback 属性はデフォルトでは true に設定され後方互換性を維持します。 ただし、 false を使用することも多々あります。
7.3. ページパラメータ リンクのコピーリンクがクリップボードにコピーされました!
7.3.1. 要求パラメータのモデルへのマッピング リンクのコピーリンクがクリップボードにコピーされました!
<param> 宣言は JSF 入力の値バインディングと同様に双方向性です。
- ビュー ID に対する Faces 以外 (GET) の要求が発生すると、 Seam は適切なタイプ変換を実行した後、 名前付きパラメータの値をそのモデルオブジェクトに設定します。
- 任意の
<s:link>や<s:button>は透過的に要求パラメータを含みます。 パラメータ値は、 レンダリングフェーズの間に (<s:link>がレンダリングされるとき) 値バインディングを評価することによって決定されます。 - そのビュー ID への
<redirect/>を持つナビゲーションルールはすべて要求パラメータを透過的に含みます。 パラメータの値はアプリケーション起動フェーズの最後で値バインディングを評価することにより決定されます。 - その値は特定のビュー ID を持つページの全 JSF フォーム送信で透過的に伝播します。 つまりビューパラメータは Faces 要求の
PAGEスコープのコンテキスト変数のように動作します。
/hello.jsp に到着し、その値は対話 (または他のサーバー側の状態) を必要とせずにメモリに保持されます。
7.4. 要求パラメータの伝播 リンクのコピーリンクがクリップボードにコピーされました!
name 属性しか指定されていない場合、 要求パラメータは PAGE コンテキストを使って伝播されます (つまり、 モデルプロパティへはマッピングされません)。
- 要求パラメータがビューのページパラメータとして記載されていると、
<s:link>や<s:button>はすべて透過的にその要求パラメータを伝播します。 - その値は特定のビュー ID を持つページの全 JSF フォーム送信で透過的に伝播されます (つまり、 ビューパラメータは Faces 要求の
PAGEスコープのコンテキスト変数のように動作します)。
7.5. ページパラメータでの URL 書き換え リンクのコピーリンクがクリップボードにコピーされました!
pages.xml 内のビューに対して発見されるパターンに応じて発生します。Seam の URL 書き換えは同一のパターンに基づいて受信および発信 URL 書き換えを行います。このプロセスの簡単なパターンを以下に示します。
<page view-id="/home.xhtml"> <rewrite pattern="/home" /> </page>
<page view-id="/home.xhtml">
<rewrite pattern="/home" />
</page>
/home の着信要求はすべて /home.xhtml に送られます。 通常は /home.seam をポイントする生成されたリンクは /home に書き換えられます。 書き換えパターンはクエリパラメータの前の URL 部分にのみ一致します。 それゆえ、 /home.seam?conversationId=13 と /home.seam?color=red は両方ともこの書き換え規則で一致します。
<page view-id="/home.xhtml">
<rewrite pattern="/home/{color}" />
<rewrite pattern="/home" />
</page>
<page view-id="/home.xhtml">
<rewrite pattern="/home/{color}" />
<rewrite pattern="/home" />
</page>
/home/red の着信要求はあたかも /home.seam?color=red であるように処理されます。 同様に、 color がページパラメータの場合は /home.seam?color=blue と通常表示される発信 URL は代わりに /home/blue と出力されます。 規則は順番に処理されるため一般的な規則より先に限定的な規則を記述することが重要です。
/search.seam?conversationId=13 は /search-13 と書き換えられます。
<page view-id="/search.xhtml">
<rewrite pattern="/search-{conversationId}" />
<rewrite pattern="/search" />
</page>
<page view-id="/search.xhtml">
<rewrite pattern="/search-{conversationId}" />
<rewrite pattern="/search" />
</page>
org.tuckey.URLRewriteFilter を使用し続ける、または Web サーバーで書き換え規則を適用させることができます。
7.6. 変換と妥当性検証 リンクのコピーリンクがクリップボードにコピーされました!
required="true" を使用することもできます。
FacesMessage が FacesContext に追加されます。
7.8. ナビゲーション、 ページアクション、 パラメータを定義するための詳細に設定されたファイル リンクのコピーリンクがクリップボードにコピーされました!
/calc/calculator.jsp を持つページのアクションやパラメータは calc/calculator.page.xml という名前のリソースに定義できます。 この場合、 <page> がルートエレメントであり、 ビュー ID は暗黙的に指定されます。
<page action="#{calculator.calculate}">
<param name="x" value="#{calculator.lhs}"/>
<param name="y" value="#{calculator.rhs}"/>
<param name="op" converter="#{operatorConverter}" value="#{calculator.op}"/>
</page>
<page action="#{calculator.calculate}">
<param name="x" value="#{calculator.lhs}"/>
<param name="y" value="#{calculator.rhs}"/>
<param name="op" converter="#{operatorConverter}" value="#{calculator.op}"/>
</page>
7.9. コンポーネント駆動イベント リンクのコピーリンクがクリップボードにコピーされました!
components.xml に指定します。
components.xml で出現する順番に従って呼び出されます。 イベントを発生させるために Seam は組み込みコンポーネントを提供します。
components.xml で定義されたメソッドバインディングはイベントを消費側にマッピングします。 アノテーションを使用してこれを行うこともできます。
7.10. コンテキスト依存イベント リンクのコピーリンクがクリップボードにコピーされました!
| イベント | 詳細 |
|---|---|
org.jboss.seam.validationFailed
|
JSFvalidation が失敗すると呼び出されます。
|
org.jboss.seam.noConversation
|
長期実行の対話が存在せず長期実行の対話が必要とされる場合に呼び出されます。
|
org.jboss.seam.preSetVariable.<name>
|
コンテキスト変数 <name> が設定されると呼び出されます。
|
org.jboss.seam.postSetVariable.<name>
|
コンテキスト変数 <name> が設定されると呼び出されます。
|
org.jboss.seam.preRemoveVariable.<name>
|
コンテキスト変数 <name> の設定が解除されると呼び出されます。
|
org.jboss.seam.postRemoveVariable.<name>
|
コンテキスト変数 <name> の設定が解除されると呼び出されます。
|
org.jboss.seam.preDestroyContext.<SCOPE>
|
<SCOPE> コンテキストが破棄される前に呼び出されます。
|
org.jboss.seam.postDestroyContext.<SCOPE>
|
<SCOPE> コンテキストが破棄された後に呼び出されます。
|
org.jboss.seam.beginConversation
|
長期実行の対話が始まるときに必ず呼び出されます。
|
org.jboss.seam.endConversation
|
長期実行の対話が終了するときに必ず呼び出されます。
|
org.jboss.seam.conversationTimeout
|
対話のタイムアウトが発生すると呼び出されます。対話 ID はパラメータとして渡されます。
|
org.jboss.seam.beginPageflow
|
ページフローが開始すると呼び出されます。
|
org.jboss.seam.beginPageflow.<name>
|
ページフロー <name> が開始すると呼び出されます。
|
org.jboss.seam.endPageflow
|
ページフローが終了すると呼び出されます。
|
org.jboss.seam.endPageflow.<name>
|
ページフロー <name> が終了すると呼び出されます。
|
org.jboss.seam.createProcess.<name>
|
プロセス <name> が作成されると呼び出されます。
|
org.jboss.seam.endProcess.<name>
|
プロセス <name> が終了すると呼び出されます。
|
org.jboss.seam.initProcess.<name>
|
プロセス <name> が対話に関連付けられると呼び出されます。
|
org.jboss.seam.initTask.<name>
|
タスク <name> が対話に関連付けられると呼び出されます。
|
org.jboss.seam.startTask.<name>
|
タスク <name> が開始すると呼び出されます。
|
org.jboss.seam.endTask.<name>
|
タスク <name> が終了すると呼び出されます。
|
org.jboss.seam.postCreate.<name>
|
コンポーネント <name> が作成されると呼び出されます。
|
org.jboss.seam.preDestroy.<name>
|
コンポーネント <name> が破棄されると呼び出されます。
|
org.jboss.seam.beforePhase
|
JSF フェーズの開始前に呼び出されます。
|
org.jboss.seam.afterPhase
|
JSF フェーズの終了後に呼び出されます。
|
org.jboss.seam.postInitialization
|
Seam により全コンポーネントの初期化および起動が終了すると呼び出されます。
|
org.jboss.seam.postReInitialization
|
再デプロイの後、Seam により全コンポーネントの再初期化および起動が終了すると呼び出されます。
|
org.jboss.seam.exceptionHandled.<type>
|
キャッチされない例外が Seam により処理されると呼び出されます。
|
org.jboss.seam.exceptionHandled
|
キャッチされない例外が Seam により処理されると呼び出されます。
|
org.jboss.seam.exceptionNotHandled
|
キャッチされない例外にハンドラがなかった場合に呼び出されます。
|
org.jboss.seam.afterTransactionSuccess
|
Seam Application Framework でトランザクションが成功すると呼び出されます。
|
org.jboss.seam.afterTransactionSuccess.<name>
|
エンティティ
<name> を管理する Seam Application Framework でトランザクションが成功すると呼び出されます。
|
org.jboss.seam.security.loggedOut
|
ユーザーがログアウトすると呼び出されます。
|
org.jboss.seam.security.loginFailed
|
ユーザー認証が失敗すると呼び出されます。
|
org.jboss.seam.security.loginSuccessful
|
ユーザーが正常に認証されると呼び出されます。
|
org.jboss.seam.security.notAuthorized
|
承認確認が失敗すると呼び出されます。
|
org.jboss.seam.security.notLoggedIn
|
認証されたユーザーがなく、認証が必要な場合に呼び出されます。
|
org.jboss.seam.security.postAuthenticate
|
ユーザーが認証された後に呼び出されます。
|
org.jboss.seam.security.preAuthenticate
|
ユーザーの認証試行の前に呼び出されます。
|
7.11. Seam インターセプタ リンクのコピーリンクがクリップボードにコピーされました!
@AroundInvoke というアノテーションが付加されたメソッドを持つクラスを記述して、 その Bean にインターセプタのクラス名を指定する @Interceptors のアノテーションを付ける必要があります。 たとえば、 次のインターセプタはアクションリスナーメソッドの呼び出しを許可する前にユーザーがログインされたかを確認します。
@Interceptors(LoggedInInterceptor.class) というアノテーションを付加しなければなりません。 ただし、 Seam はクラスレベルのインターセプタ (@Target(TYPE) アノテーションが付与されたもの) 用にメタアノテーションとして @Interceptors を使えるようにすることで、EJB3 でのインターセプタフレームワーク上に構築されます。 以下の例では、 @LoggedIn アノテーションを生成します。
@Target(TYPE)
@Retention(RUNTIME)
@Interceptors(LoggedInInterceptor.class)
public @interface LoggedIn {}
@Target(TYPE)
@Retention(RUNTIME)
@Interceptors(LoggedInInterceptor.class)
public @interface LoggedIn {}
@LoggedIn アノテーションを付与しインターセプタを適用することができます。
@Interceptor アノテーションを追加してインターセプタの特定の順序を指定します。
@Interceptor(type=CLIENT)
public class LoggedInInterceptor {
...
}
@Interceptor(type=CLIENT)
public class LoggedInInterceptor {
...
}
@Interceptor(stateless=true) が指定されます。
@AroundInvoke を使った) ビジネスメソッドだけでなく、ライフサイクルメソッドの @PostConstruct、 @PreDestroy、 @PrePassivate そして @PostActive に対しても定義します。Seam はコンポーネントおよびインターセプタの両方でこれらのライフサイクルのメソッドを EJB3 Bean のみならず JavaBean コンポーネントに対してもサポートします (JavaBean コンポーネントにとって意味のない @PreDestroy は除きます)。
7.12. 例外の管理 リンクのコピーリンクがクリップボードにコピーされました!
@ApplicationException アノテーションと組み合わされ、例外がトランザクションロールバックの原因となるかどうかを指定します。
7.12.1. 例外およびトランザクション リンクのコピーリンクがクリップボードにコピーされました!
@ApplicationException(rollback=true) が指定されるとロールバックが発生します (アプリケーション例外とはすべてのチェック例外、 または @ApplicationException アノテーションが付いたすべての非チェック例外です。 システム例外とは @ApplicationException アノテーションがないすべての非チェック例外です)。
注記
7.12.2. Seam の例外処理を有効にする リンクのコピーリンクがクリップボードにコピーされました!
web.xml で宣言する必要があります。
web.xml で Facelets 開発モードを無効にし components.xml で Seam デバッグモードを無効にする必要があります。
7.12.3. 例外処理に対するアノテーションの使用 リンクのコピーリンクがクリップボードにコピーされました!
@HttpError(errorCode=404)
public class ApplicationException extends Exception {
...
}
@HttpError(errorCode=404)
public class ApplicationException extends Exception {
...
}
注記
RENDER_RESPONSE フェーズ中に発生する例外は処理できません。一度応答の出力が開始するとリダイレクトを実行することができないからです。
viewId を指定することも可能です。
@Redirect(viewId="/error.xhtml", message="Unexpected error")
public class SystemException extends RuntimeException {
...
}
@Redirect(viewId="/error.xhtml", message="Unexpected error")
public class SystemException extends RuntimeException {
...
}
7.12.4. 例外処理に対する XML の使用 リンクのコピーリンクがクリップボードにコピーされました!
pages.xml でも指定できるようにしています。
<exception> 宣言はクラスを指定していないので、 アノテーションまたは pages.xml で指定された処理なしですべての例外に対してキャッチオールで動作します。
view-id を指定することもできます。
org.jboss.seam.handledException は例外ハンドラによって処理されたネストした例外を保持します。 その最も外側の (ラッパーの) 例外は org.jboss.seam.caughtException によって取得可能です。
7.12.4.1. 例外のロギングの抑制 リンクのコピーリンクがクリップボードにコピーされました!
pages.xml で定義されている例外ハンドラの場合、 例外がログ記録されるレベルを指定したり、 例外のログ記録を全て抑制することが可能です。 log および log-level の各属性を使用して例外のロギングを制御します。 以下に示すように、 log="false" が設定されている場合に指定された例外が発生するとログメッセージは生成されません。
log 属性を指定しないとデフォルトでは true に設定されます。 つまり例外はログ記録されます。 代わりに log-level を指定して例外がログ記録されるレベルを制御することができます。
log-level に指定できる値は、 fatal、 error、 warn、 info、 debug、 trace です。 log-level を指定しない、または無効な値を設定した場合は、 log-level はデフォルトで error に設定されます。
7.12.5. 共通の例外 リンクのコピーリンクがクリップボードにコピーされました!
<exception class="org.jboss.seam.framework.EntityNotFoundException">
<redirect view-id="/error.xhtml">
<message>Not found</message>
</redirect>
</exception>
<exception class="org.jboss.seam.framework.EntityNotFoundException">
<redirect view-id="/error.xhtml">
<message>Not found</message>
</redirect>
</exception>
<exception class="javax.Faces.application.ViewExpiredException">
<redirect view-id="/error.xhtml">
<message>Your session has timed out, please try again</message>
</redirect>
</exception>
<exception class="javax.Faces.application.ViewExpiredException">
<redirect view-id="/error.xhtml">
<message>Your session has timed out, please try again</message>
</redirect>
</exception>
ViewExpiredException が発生します。 「長期実行の対話の必要」 で説明した conversation-required と no-conversation-view-id の設定により対話内で使用されたページにアクセスしながら、 セッションの有効期限に対して細かな制御が可能になります。
第8章 対話とワークスペースの管理 リンクのコピーリンクがクリップボードにコピーされました!
- ワークスペース というコンセプトと、効率的なワークスペースの管理。
- 楽観的なセマンティクスの アプリケーショントランザクション というコンセプト。 ステートレスアーキテクチャをベースとする既存のフレームワークでは、拡張永続のコンテキストを効率的に管理することはできませんでした。
- ワークフロー タスク というコンセプト。
8.1. Seam の対話モデル リンクのコピーリンクがクリップボードにコピーされました!
- JSF 要求ライフサイクルのレスポンス出力フェーズ、 アプリケーション起動フェーズ、モデル値の更新フェーズ、バリデーション実行フェーズ、リクエスト値の適用フェーズなどの間は対話コンテキストは常にアクティブとなります。
- JSF 要求ライフサイクルのビュー復元フェーズの終了時に、Seam はそれまでの長期実行の全対話コンテキストの復元を試みます。 長期実行の対話コンテキストが存在しない場合は、Seam は一時的な新しい対話コンテキストを作成します。
@Beginメソッドが出てくると、 一時的な対話コンテキストは長期実行の対話に昇格します。@Endメソッドが出てくると、 すべての長期実行の対話コンテキストは一時的な対話に降格されます。- JSF 要求ライフサイクルであるレスポンス出力フェーズの終わりには、Seam は長期実行の対話コンテキストの内容を記憶するか、 一時的な対話コンテキストの内容を破棄します。
- Faces 要求 (JSF ポストバック) はすべて対話コンテキストを伝播します。 デフォルトでは、 Faces ではない要求 (GET 要求など) は対話コンテキストを伝播しません。
- JSF 要求のライフサイクルがリダイレクトで短縮される場合、 対話が既に
@End(beforeRedirect=true)で終了されていない限り Seam は透過的に現在の対話コンテキストを格納して復元します。
<a href="main.jsf?#{manager.conversationIdParameter}=#{conversation.id}">
Continue
</a>
<a href="main.jsf?#{manager.conversationIdParameter}=#{conversation.id}">
Continue
</a>
<h:outputLink value="main.jsf">
<f:param name="#{manager.conversationIdParameter}"
value="#{conversation.id}"/>
<h:outputText value="Continue"/>
</h:outputLink>
<h:outputLink value="main.jsf">
<f:param name="#{manager.conversationIdParameter}"
value="#{conversation.id}"/>
<h:outputText value="Continue"/>
</h:outputLink>
<h:outputLink value="main.jsf"> <s:conversationId/> <h:outputText value="Continue"/> </h:outputLink>
<h:outputLink value="main.jsf">
<s:conversationId/>
<h:outputText value="Continue"/>
</h:outputLink>
<h:commandLink action="main" value="Exit"> <f:param name="conversationPropagation" value="none"/> </h:commandLink>
<h:commandLink action="main" value="Exit">
<f:param name="conversationPropagation" value="none"/>
</h:commandLink>
<h:commandLink action="main" value="Exit"> <s:conversationPropagation type="none"/> </h:commandLink>
<h:commandLink action="main" value="Exit">
<s:conversationPropagation type="none"/>
</h:commandLink>
注記
conversationPropagation 要求パラメータまたは <s:conversationPropagation> タグを使って対話の開始と終了を行う、またはネストされた対話を開始することができます。
<h:commandLink action="main" value="Exit"> <s:conversationPropagation type="end"/> </h:commandLink>
<h:commandLink action="main" value="Exit">
<s:conversationPropagation type="end"/>
</h:commandLink>
<h:commandLink action="main" value="Select Child"> <s:conversationPropagation type="nested"/> </h:commandLink>
<h:commandLink action="main" value="Select Child">
<s:conversationPropagation type="nested"/>
</h:commandLink>
<h:commandLink action="main" value="Select Hotel"> <s:conversationPropagation type="begin"/> </h:commandLink>
<h:commandLink action="main" value="Select Hotel">
<s:conversationPropagation type="begin"/>
</h:commandLink>
<h:commandLink action="main" value="Select Hotel"> <s:conversationPropagation type="join"/> </h:commandLink>
<h:commandLink action="main" value="Select Hotel">
<s:conversationPropagation type="join"/>
</h:commandLink>
- 対話には、 連続的に実行したり同時に実行する多くの小さな単位のユーザーの操作も含まれます。より小さい ネストされた対話 には単独の対話状態セットがあり、また外側の対話状態へのアクセスもあります。
- ユーザーは同じブラウザのウィンドウ内でいくつもの対話を切り換えることができます。 この機能は ワークスペース管理 と呼ばれます。
8.2. ネストされた対話 リンクのコピーリンクがクリップボードにコピーされました!
@Begin(nested=true) とマークされたメソッドを呼び出すことにより作成されます。 ネストされた対話にはそれ自体の対話コンテキストがありますが、 外側の対話のコンテキストから値を読み取ることができます。外側の対話のコンテキストはネストされた対話内では読み取り専用ですが、オブジェクトは参照により取得されるため、オブジェクト自体への変更はその外側のコンテキストに反映されます。
- 対話をネストするとオリジナルの対話または外側の対話のコンテキストに積み重ねられるコンテキストを初期化します。 外側の対話が親とみなされます。
- ネストされた対話のコンテキストに直接設定されるまたはアウトジェクトされる値はすべて親となる対話のコンテキストでアクセス可能なオブジェクトに影響は与えません。
- 対話コンテキストからのコンテキスト検索やインジェクションはまず現在の対話コンテキストにある値を検索します。値が見付からないと対話がネストされている場合はその対話スタックまで続きます。この動作は上書き可能です。
@End が出てくると、 ネストされた対話は破棄されて外側の対話が開始し、 対話スタックを ポップ します。 対話は任意の深さにネストすることができます。
@End(root=true) を指定すると宣言的にこれを行うことができます。
@PerNestedConversation アノテーションを付けます。
8.3. GET 要求を使った対話の開始 リンクのコピーリンクがクリップボードにコピーされました!
<h:outputLink> からそのページに移動する場合に発生します。
@Begin アノテーションを付けることはできません。
@Create メソッドでその状態をフェッチできます。 状態が保持されていなければ、 コンテキスト変数に対して @Factory メソッドを定義することができます。
pages.xml ファイルに ページアクション を定義することができます。
<pages>
<page view-id="/messageList.jsp" action="#{messageManager.list}"/>
...
</pages>
<pages>
<page view-id="/messageList.jsp" action="#{messageManager.list}"/>
...
</pages>
<pages>
<page view-id="/messageList.jsp" action="#{conversation.begin}"/>
...
</pages>
<pages>
<page view-id="/messageList.jsp" action="#{conversation.begin}"/>
...
</pages>
#{conversation.end} を使って対話を終了します。
<begin-conversation> エレメントを使用することができます。
<end-conversation> エレメントもあります。
@Createメソッドに@Beginアノテーションを追加する@Factoryメソッドに@Beginアノテーションを追加する- Seam ページアクションメソッドに
@Beginアノテーションを追加する pages.xmlで<begin-conversation>を使用する#{conversation.begin}を Seam ページアクションメソッドとして使用する
8.4. 長期実行の対話の必要 リンクのコピーリンクがクリップボードにコピーされました!
conversation-required 属性があり、 ページのレンダリングが行われるには現在の対話が長期実行で (またはネストされている) なければならないことを示すことができます。
<page view-id="/book.xhtml" conversation-required="true"/>
<page view-id="/book.xhtml" conversation-required="true"/>
注記
org.jboss.seam.noConversationというコンテキスト依存イベントを発生させます。org.jboss.seam.NoConversationバンドルキーを持つ警告ステータスのメッセージを登録します。- 次のように、
no-conversation-view-id属性で定義されている場合はユーザーを代替となるページにリダイレクトします。<pages no-conversation-view-id="/main.xhtml"/>
<pages no-conversation-view-id="/main.xhtml"/>Copy to Clipboard Copied! Toggle word wrap Toggle overflow このページはアプリケーション全体で使用されます。 現在、 代替ページを複数定義することはできません。
8.5. と の使用 リンクのコピーリンクがクリップボードにコピーされました!
<h:outputLink> を使用する必要があります。 ただし、 このメソッドには重要な制限が 2 つあります。
- JSF にはアクションリスナーを
<h:outputLink>につなげる方法は備わっていません。 - また、実際のフォームサブミットがないため JSF は選択された
DataModelの行を伝播しません。
@DataModel と @DataModelSelection が透過的かつ便利です。
<s:link> JSF タグを提供します。
<s:link view="/login.xhtml" value="Login"/>
<s:link view="/login.xhtml" value="Login"/>
<s:link action="#{login.logout}" value="Logout"/>
<s:link action="#{login.logout}" value="Logout"/>
<s:link view="/loggedOut.xhtml" action="#{login.logout}" value="Logout"/>
<s:link view="/loggedOut.xhtml" action="#{login.logout}" value="Logout"/>
<h:dataTable> 内で使用する DataModel の選択された行を自動的に伝播します。
<s:link view="/hotel.xhtml" action="#{hotelSearch.selectHotel}"
value="#{hotel.name}"/>
<s:link view="/hotel.xhtml" action="#{hotelSearch.selectHotel}"
value="#{hotel.name}"/>
<s:link view="/main.xhtml" propagation="none"/>
<s:link view="/main.xhtml" propagation="none"/>
<s:link action="#{issueEditor.viewComment}" propagation="nest"/>
<s:link action="#{issueEditor.viewComment}" propagation="nest"/>
<s:link action="#{documentEditor.getDocument}" propagation="begin"
pageflow="EditDocument"/>
<s:link action="#{documentEditor.getDocument}" propagation="begin"
pageflow="EditDocument"/>
taskInstance 属性は jBPM タスクリストで使用します。例は 「Seam と jBPM を使ったアプリケーションの全容 : DVD ストアサンプル」 を参照してください。
<s:link action="#{documentApproval.approveOrReject}"
taskInstance="#{task}"/>
<s:link action="#{documentApproval.approveOrReject}"
taskInstance="#{task}"/>
<s:button> を使用します。
<s:button action="#{login.logout}" value="Logout"/>
<s:button action="#{login.logout}" value="Logout"/>
8.6. 成功のメッセージ リンクのコピーリンクがクリップボードにコピーされました!
FacesMessage を使うと便利です。ただし、成功のアクションは多くの場合ブラウザリダイレクトを必要とします。JSF はリダイレクト全体に Faces のメッセージを伝播しないため、純粋な JSF で成功のメッセージを表示するのは困難です。
facesMessages がこの問題を解決します (これには Seam リダイレクトフィルタが必要です)。
facesMessages に追加されると、次のレスポンス出力フェーズで現在の対話に対して使用されます。Seam はリダイレクト全体で一時的な対話コンテキストも維持するため、長期実行の対話がなくても機能します。
facesMessages.add("Document #{document.title} was updated");
facesMessages.add("Document #{document.title} was updated");
<h:messages globalOnly="true"/>
<h:messages globalOnly="true"/>
8.7. ナチュラル対話の ID リンクのコピーリンクがクリップボードにコピーされました!
http://seam-hotels/book.seam?hotel=BestWesternAntwerpen は http://seam-hotels/book/BestWesternAntwerpen と書き換えられるため、 非常にわかりやすくなります。 URLRewrite はパラメータに依存する点に注意してください。 前のサンプルの hotel はドメインモデルで一意のパラメータにマッピングを行わなければなりません。
8.8. ナチュラル対話の作成 リンクのコピーリンクがクリップボードにコピーされました!
pages.xml で定義されます。
<conversation name="PlaceBid" parameter-name="auctionId"
parameter-value="#{auction.auctionId}"/>
<conversation name="PlaceBid" parameter-name="auctionId"
parameter-value="#{auction.auctionId}"/>
PlaceBid です。 対話名は一意的にこの特定の名前が付いた対話を識別し、page 定義を使用して参加する名前の付いた対話を識別します。
parameter-name はナチュラル対話 ID を保持してデフォルトの対話 ID パラメータを置換する要求パラメータを定義します。 この例では parameter-name は auctionId です。 つまり、 ページの URL 内に cid=123 のような対話パラメータではなく auctionId=765432 を含むようになります。
parameter-value は対話 ID として使用するナチュラルビジネスキーの値の評価に使用される EL 式を定義します。 この例では対話 ID が現在スコープ内にある auction インスタンスの主キーの値になります。
page 定義の conversation 属性を指定することで実行できます。
8.9. ナチュラル対話へのリダイレクト リンクのコピーリンクがクリップボードにコピーされました!
#{bidAction.placeBid} を呼び出すことによりナチュラル対話 ID PlaceBid で設定された /bid.xhtml にリダイレクトされるのがわかります。 アクションメソッドの宣言は以下のようになります。
@Begin(join = true) public void placeBid()
@Begin(join = true)
public void placeBid()
<page/> エレメントで指定されると、 その名前が付いた対話へのリダイレクトはアクションメソッドの呼び出しに続いてナビゲーションルールの一部として発生します。既存の対話にリダイレクトする場合は、これが問題となることがあります。アクションメソッドが呼び出される前にリダイレクトが発生する必要があるためです。したがってアクションが呼び出される前に対話名を指定する必要があります。これを行う方法のひとつとして s:conversationName タグの使用があります。
<h:commandButton id="placeBidWithAmount" styleClass="placeBid"
action="#{bidAction.placeBid}">
<s:conversationName value="PlaceBid"/>
</h:commandButton>
<h:commandButton id="placeBidWithAmount" styleClass="placeBid"
action="#{bidAction.placeBid}">
<s:conversationName value="PlaceBid"/>
</h:commandButton>
s:link または s:button のいずれかに conversationName 属性を指定することもできます。
<s:link value="Place Bid" action="#{bidAction.placeBid}"
conversationName="PlaceBid"/>
<s:link value="Place Bid" action="#{bidAction.placeBid}"
conversationName="PlaceBid"/>
8.10. ワークスペースの管理 リンクのコピーリンクがクリップボードにコピーされました!
- それぞれのビュー ID (JSF または Seam ナビゲーションルールを使用する場合) またはページノード (jPDL ページフローを使用する場合) に 記述 テキストを入力します。ワークスペースを切り替えることで、この記述テキストをユーザーに表示します。
- ページの中に 1 つ以上のワークスペース切り替え JSP または Facelets の一部を含ませます。 標準の断片はドロップダウンメニュー、 対話のリスト、「ブレッドクラム」を通じてワークスペース管理をサポートします。
8.10.1. ワークスペース管理と JSF ナビゲーション リンクのコピーリンクがクリップボードにコピーされました!
view-id を復元してその対話に切り替えます。 ワークスペースの記述テキストは pages.xml と呼ばれるファイルで定義され、 Seam はこのファイルが WEB-INF ディレクトリ内に faces-config.xml と共に配置されているようにします。
注記
8.10.2. ワークスペース管理と jPDL ページフロー リンクのコピーリンクがクリップボードにコピーされました!
view-id に現在の <page> ノードに応じて異なる記述を持つことができるためより柔軟なモデルとなります。記述テキストは <page> ノードで定義されます。
8.10.3. 対話切り替え リンクのコピーリンクがクリップボードにコピーされました!
pages.xml で指定) のみがドロップダウンメニューに含まれます。
8.10.4. 対話一覧 リンクのコピーリンクがクリップボードにコピーされました!
8.10.5. ブレッドクラム リンクのコピーリンクがクリップボードにコピーされました!
<ui:repeat value="#{conversationStack}" var="entry">
<h:outputText value=" | "/>
<h:commandLink value="#{entry.description}" action="#{entry.select}"/>
</ui:repeat>
<ui:repeat value="#{conversationStack}" var="entry">
<h:outputText value=" | "/>
<h:commandLink value="#{entry.description}" action="#{entry.select}"/>
</ui:repeat>
8.11. 対話型コンポーネントと JSF コンポーネントのバインディング リンクのコピーリンクがクリップボードにコピーされました!
facesMessages のような Seam の組み込みコンポーネントが含まれます。
uiComponent ハンドルで JSF コンポーネントツリーにアクセスすることもできます。 次の例では反復中にデータテーブルを支える UIData コンポーネントの getRowIndex() にアクセスし、 現在の行番号を表示します。
8.12. 対話型コンポーネントへの同時呼び出し リンクのコピーリンクがクリップボードにコピーされました!
<core:manager concurrent-request-timeout="500" />
<core:manager concurrent-request-timeout="500" />
<page view-id="/book.xhtml" conversation-required="true"
login-required="true" concurrent-request-timeout="2000" />
<page view-id="/book.xhtml" conversation-required="true"
login-required="true" concurrent-request-timeout="2000" />
8.12.1. 対話型 AJAX アプリケーションを設計する方法 リンクのコピーリンクがクリップボードにコピーされました!
@Asynchronous をマークしてポーリングの間隔を決定するだけです。
8.12.2. エラー処理 リンクのコピーリンクがクリップボードにコピーされました!
concurrent-request-timeout の期限が切れるまでに全要求は処理されなくなります。 こうした場合、 Seam は ConcurrentRequestTimeoutException を送出します。これは pages.xml で処理されます。 HTTP 503 エラーの送信が推奨されます。
<exception class="org.jboss.seam.ConcurrentRequestTimeoutException"
log-level="trace">
<http-error error-code="503" />
</exception>
<exception class="org.jboss.seam.ConcurrentRequestTimeoutException"
log-level="trace">
<http-error error-code="503" />
</exception>
注記
<script type="text/javascript">
A4J.AJAX.onError = function(req,status,message) {
alert("An error occurred");
};
</script>
<script type="text/javascript">
A4J.AJAX.onError = function(req,status,message) {
alert("An error occurred");
};
</script>
<script type="text/javascript">
A4J.AJAX.onExpired = function(loc,message) {
alert("View expired");
};
</script>
<script type="text/javascript">
A4J.AJAX.onExpired = function(loc,message) {
alert("View expired");
};
</script>
AJAX_VIEW_EXPIRED=View expired. Please reload the page.
AJAX_VIEW_EXPIRED=View expired. Please reload the page.
8.12.3. RichFaces (Ajax4jsf) リンクのコピーリンクがクリップボードにコピーされました!
eventsQueue- イベントが置かれる待ち行列を提供します。 イベントはすべて待ち行列に入れられ要求がサーバーに連続的に送られます。サーバーが溢れるのを防ぐため、サーバーに対する要求の実行に一定の時間がかかる場合に便利です (重量のある計算で低速のソースから情報を取得する場合など)。
ignoreDupResponses- より新しい「同様な」要求がすでに行列待ちにある場合はこの要求によって生成された応答を無視します。
ignoreDupResponses="true"はサーバー側の要求処理を取り消す わけではありません。 クライアント側での不要な更新を防ぐだけです。このオプションは複数の同時要求を許可するため、 Seam の対話で使用する場合は注意が必要です。 requestDelay- 要求がキューに残っている時間をミリ秒単位で定義します。要求がこの時点で処理されていない場合は、要求は送信されるか (応答が受信されているかどうかにかかわらず) 破棄 (より新しい「同様」のイベントがキューにある場合) されます。このオプションは複数の同時要求を許可するため、 Seam の対話で使用する場合は注意が必要です。 アクションが実行に要する時間より設定する遅延 (同時要求のタイムアウトと併用) の方が長くなければなりません。
<a:poll reRender="total" interval="1000" />- 必要に応じてサーバーにポーリングし、エリアを再レンダリングします。
第9章 ページフローとビジネスプロセス リンクのコピーリンクがクリップボードにコピーされました!
注記
注記
9.1. Seam のページフロー リンクのコピーリンクがクリップボードにコピーされました!
- JSF あるいは Seam ナビゲーションルールを使用します - ステートレスなナビゲーションモデル
- jPDL を使用します - ステートフルなナビゲーションモデル
9.1.1. 2 種類のナビゲーションモデル リンクのコピーリンクがクリップボードにコピーされました!
public String search() {
return "/searchResults.jsp?searchPattern=#{searchAction.searchPattern}";
}
public String search() {
return "/searchResults.jsp?searchPattern=#{searchAction.searchPattern}";
}
- JSF と Seam ナビゲーションルールは非常にシンプルです。 (しかし、 根底となる Java コードはより複雑であるという事実を隠しています。)
- jPDL によりユーザー操作がとたんに理解しやすくなるため、 JSP や Java コードを見る必要性がなくなります。
9.1.2. Seam と戻るボタン リンクのコピーリンクがクリップボードにコピーされました!
no-conversation-view-id を null チェックと組合わせるだけです。 大抵望まれるものは自由なナビゲーションへの対応となります。
no-conversation-view-id の宣言は pages.xml で行います。 現在は存在していない対話で表示されたページからの要求の場合には別のページにリダイレクトを行うよう指示します。
<page view-id="/checkout.xhtml" no-conversation-view-id="/main.xhtml"/>
<page view-id="/checkout.xhtml" no-conversation-view-id="/main.xhtml"/>
back="enabled" を設定すると特定のページノードからの戻るボタン操作を許可することができます。
checkout 状態から以前のどの状態にでも戻るボタンでの移動が可能です。
注記
no-conversation-view-id 宣言はページフロー定義で行います。
9.2. jPDL ページフローの使用 リンクのコピーリンクがクリップボードにコピーされました!
9.2.1. ページフローのインストール リンクのコピーリンクがクリップボードにコピーされました!
seam.properties ファイルを含むアーカイブ) の中にページフローの定義 (標準の .jpdl.xml 拡張を使用) を配置する必要があります。
<bpm:jbpm />
<bpm:jbpm />
components.xml で指定します。
9.2.2. ページフローの開始 リンクのコピーリンクがクリップボードにコピーされました!
@Begin、 @BeginTask または @StartTask のアノテーションを使用してプロセス定義の名前を指定し jPDL ベースのページフローを「開始」します。
@Begin(pageflow="numberguess") public void begin() { ... }
@Begin(pageflow="numberguess") public void begin() { ... }
pages.xml を使用してページフローを開始できます。
<page> <begin-conversation pageflow="numberguess"/> </page>
<page>
<begin-conversation pageflow="numberguess"/>
</page>
RENDER_RESPONSE フェーズ中 — 例えば、 @Factory または @Create メソッド中 — にページフローを開始している場合は、ページは既にレンダリングされたとして考え <start-page> ノードを上記の例のようにページフロー内の最初のノードとして使用します。
<start-state> をページフローの最初のノードとして使用し、 可能性のある結果それぞれに対して遷移を宣言します。
9.2.3. ページノードと遷移 リンクのコピーリンクがクリップボードにコピーされました!
<page> ノードは、システムがユーザー入力を待っている状態を表します。
view-id は JSF のビュー ID です。 <redirect/> エレメントは JSF ナビゲーションルールにある <redirect/> と同じ効果をもたらします。 つまり、 post-then-redirect の動作をしてブラウザの更新ボタンに関する問題に対応します。 (Seam はこれらブラウザのリダイレクト全体に対話コンテキストを伝播するため、 Ruby on Rails 系の フラッシュ 構造は必要としません。)
numberGuess.jsp のコマンドボタンまたはコマンドリンクをクリックすると起こる JSF 結果の名前です。
<h:commandButton type="submit" value="Guess" action="guess"/>
<h:commandButton type="submit" value="Guess" action="guess"/>
numberGuess コンポーネントの guess () メソッドを呼び出して遷移のアクションを起動します。 jPDL でアクションの指定に使用される構文は普通の JSF EL 式であり、 遷移のハンドラは現在の Seam コンテキストにある Seam コンポーネントのメソッドになります。 従って、 JSF イベント用のイベントモデルと同じイベントモデルを jBPM イベント用に持つことになります。これは Seam で従うべき原則の 1 つです。
action が定義されていないコマンドボタンなど)、 Seam は名前のない遷移のサインがあればそれを送信します。 すべての遷移に名前が付けられている場合には単純にそのページを再表示します。 したがって次のようにこのボタンとページフローを単純化することができます。
<h:commandButton type="submit" value="Guess"/>
<h:commandButton type="submit" value="Guess"/>
<h:commandButton type="submit" value="Guess"
action="#{numberGuess.guess}"/>
<h:commandButton type="submit" value="Guess"
action="#{numberGuess.guess}"/>
<page name="displayGuess" view-id="/numberGuess.jsp"> <transition name="correctGuess" to="win"/> <transition name="incorrectGuess" to="evaluateGuess"/> </page>
<page name="displayGuess" view-id="/numberGuess.jsp">
<transition name="correctGuess" to="win"/>
<transition name="incorrectGuess" to="evaluateGuess"/>
</page>
9.2.4. フローの制御 リンクのコピーリンクがクリップボードにコピーされました!
<decision> ノードは必要になります。
<decision name="evaluateGuess" expression="#{numberGuess.correctGuess}">
<transition name="true" to="win"/>
<transition name="false" to="evaluateRemainingGuesses"/>
</decision>
<decision name="evaluateGuess" expression="#{numberGuess.correctGuess}">
<transition name="true" to="win"/>
<transition name="false" to="evaluateRemainingGuesses"/>
</decision>
9.2.5. フローの終了 リンクのコピーリンクがクリップボードにコピーされました!
<end-conversation> または @End を使用して対話を終了します。 読みやすいよう両方とも使用した方がいいでしょう。
<page name="win" view-id="/win.jsp"> <redirect/> <end-conversation/> </page>
<page name="win" view-id="/win.jsp">
<redirect/>
<end-conversation/>
</page>
transition 名を指定することができます。 この場合 Seam は包括的なビジネスプロセスで現在のタスクの終了サインを送信します。
<page name="win" view-id="/win.jsp"> <redirect/> <end-task transition="success"/> </page>
<page name="win" view-id="/win.jsp">
<redirect/>
<end-task transition="success"/>
</page>
9.2.6. ページフローの構成 リンクのコピーリンクがクリップボードにコピーされました!
<process-state> ノードは外部のページフローを中断させてから指定ページフローの実行を開始します。
<process-state name="cheat"> <sub-process name="cheat"/> <transition to="displayGuess"/> </process-state>
<process-state name="cheat">
<sub-process name="cheat"/>
<transition to="displayGuess"/>
</process-state>
<start-state> ノードで内側のフローは開始します。 <end-state> ノードの到着すると、内側のフローは終了し、外側のフローは <process-state> 要素で定義された遷移から再開されます。
9.3. Seam のビジネスプロセス管理 リンクのコピーリンクがクリップボードにコピーされました!
BUSINESS_PROCESS コンテキストに格納し、 jBPM 変数でその状態を永続にすることもできます。
<page> ノードではなく <task-node> ノードを使用するという点以外、 シンプルなビジネスプロセス定義はページフロー定義によく似ています。 長期実行のビジネスプロセスでは、 ユーザーによりログインが行われタスクが実行されるのをシステムが待っている場合に待ち状態が起こります。
<task> は <pageflow-definition> ページフロー全体に該当します。
9.4. jPDL ビジネスプロセス定義の使用 リンクのコピーリンクがクリップボードにコピーされました!
9.4.1. プロセス定義のインストール リンクのコピーリンクがクリップボードにコピーされました!
components.xml からプロセス定義をインストールする必要があるのはアプリケーション開発時のみです。
9.4.2. actor ID の初期化 リンクのコピーリンクがクリップボードにコピーされました!
actor と呼ばれる組み込み Seam コンポーネントを使用して現在の actor ID を指定します。
9.4.3. ビジネスプロセスの初期化 リンクのコピーリンクがクリップボードにコピーされました!
@CreateProcess アノテーションを使用します。
@CreateProcess(definition="todo")
public void createTodo() { ... }
@CreateProcess(definition="todo")
public void createTodo() { ... }
pages.xml を使用してビジネスプロセスを初期化することもできます。
<page> <create-process definition="todo" /> </page>
<page>
<create-process definition="todo" />
</page>
9.4.4. タスクの割り当て リンクのコピーリンクがクリップボードにコピーされました!
<task name="todo" description="#{todoList.description}">
<assignment actor-id="#{actor.id}"/>
</task>
<task name="todo" description="#{todoList.description}">
<assignment actor-id="#{actor.id}"/>
</task>
<task name="todo" description="#{todoList.description}">
<assignment pooled-actors="employees"/>
</task>
<task name="todo" description="#{todoList.description}">
<assignment pooled-actors="employees"/>
</task>
9.4.5. タスクリスト リンクのコピーリンクがクリップボードにコピーされました!
pooledTaskInstanceList は ユーザーが自分自身に割り当てることができるプールされたタスクのリストです。
<s:link> の代わりに普通の JSF <h:commandLink> を使用することもできます。
<h:commandLink action="#{pooledTask.assignToCurrentActor}">
<f:param name="taskId" value="#{task.id}"/>
</h:commandLink>
<h:commandLink action="#{pooledTask.assignToCurrentActor}">
<f:param name="taskId" value="#{task.id}"/>
</h:commandLink>
pooledTask コンポーネントは、単純にタスクを現在のユーザーに割り当てる組み込みコンポーネントです。
taskInstanceListForType コンポーネントは、 現在のユーザーに割り当てられた特定タイプのタスクを含んでいます。
9.4.6. タスクの実行 リンクのコピーリンクがクリップボードにコピーされました!
@StartTask または @BeginTask を使用します。
@StartTask public String start() { ... }
@StartTask public String start() { ... }
pages.xml を使用してタスクを開始することもできます。
<page> <start-task /> </page>
<page>
<start-task />
</page>
@EndTask で対話を終了すると Seam はタスクの完了サインを送信します。
@EndTask(transition="completed")
public String completed() { ... }
@EndTask(transition="completed")
public String completed() { ... }
pages.xml を使用することもできます。
<page> <end-task transition="completed" /> </page>
<page>
<end-task transition="completed" />
</page>
pages.xml に遷移を指定することもできます。
第10章 Seam とオブジェクト / リレーショナルマッピング リンクのコピーリンクがクリップボードにコピーされました!
10.1. はじめに リンクのコピーリンクがクリップボードにコピーされました!
LazyInitializationException の原因となっています。 ここで必要なのはアプリケーション層で楽観的トランザクションを表現する構成概念です。
- ステートフルセッション Bean の寿命はウェブ層でコードにより手作業で管理されなければなりません。
- 同じ楽観的トランザクション内のステートフルコンポーネント間での永続コンテキストの伝播は可能ですが非常に複雑です。
10.2. Seam 管理トランザクション リンクのコピーリンクがクリップボードにコピーされました!
- リクエストがいくつかの疎結合コンポーネントによる処理を必要とし、それぞれのコンポーネントが Web 層から個別に呼び出される場合です。 Seam でリクエストごと Web 層から EJB コンポーネントへの呼び出しが複数あるのはよく見られることです。
- ビューのレンダリングに関連の遅延フェッチが必要な場合です。
LazyInitializationException が引き起こされました。
- Seam はトランザクションではなく対話に対してスコープされる拡張永続コンテキストを使用します。
- Seam は要求ごとに 2 つのトランザクションを使用します。 1 番目はビュー復元フェーズの開始からアプリケーション起動フェーズの終わりまでに渡り、2 番目はレスポンス出力フェーズまでに渡ります (アプリケーションの中には、 最初のフェーズがこれより後のリクエスト値の適用フェーズの開始時に始まるものもあります)。
10.2.1. Seam 管理トランザクションを無効にする リンクのコピーリンクがクリップボードにコピーされました!
components.xml で無効にすることができます。
<core:init transaction-management-enabled="false"/> <transaction:no-transaction />
<core:init transaction-management-enabled="false"/>
<transaction:no-transaction />
10.2.2. Seamトランザクションマネージャの設定 リンクのコピーリンクがクリップボードにコピーされました!
components.xml に EJB 同期化コンポーネントをインストールしてください。
<transaction:ejb-transaction />
<transaction:ejb-transaction />
javax.persistence.EntityTransactionインターフェースで JPA RESOURCE_LOCAL 管理のトランザクションを設定します。EntityTransactionはリクエスト値の適用フェーズの開始時にトランザクションを開始します。org.hibernate.Transactionインターフェースで Hibernate 管理のトランザクションを設定します。HibernateTransactionはリクエスト値の適用フェーズの開始時にトランザクションを開始します。org.springframework.transaction.PlatformTransactionManagerインターフェースで Spring 管理トランザクションを設定します。 Spring のPlatformTransactionManagementマネージャはuserConversationContext属性を設定するとリクエスト値の適用フェーズの開始時にトランザクションを開始することができます。- Seam 管理トランザクションを明示的に無効にします。
components.xml に次を追加して JPA RESOURCE_LOCAL トランザクション管理を設定します。 #{em} は persistence:managed-persistence-context コンポーネント名です。 管理永続コンテキスト名が entityManager なら entity-manager 属性を省略することができます (詳細は 「Seam 管理永続コンテキスト」 を参照)。
<transaction:entity-transaction entity-manager="#{em}"/>
<transaction:entity-transaction entity-manager="#{em}"/>
components.xml で次を宣言します。#{hibernateSession} はプロジェクトの persistence:managed-hibernate-session コンポーネント名です。 管理 Hibernate セッション名が session なら session 属性を省略することができます (詳細は 「Seam 管理永続コンテキスト」を参照)。
<transaction:hibernate-transaction session="#{hibernateSession}"/>
<transaction:hibernate-transaction session="#{hibernateSession}"/>
components.xml で宣言します。
<transaction:no-transaction />
<transaction:no-transaction />
10.2.3. トランザクションの同期化 リンクのコピーリンクがクリップボードにコピーされました!
beforeCompletion() や afterCompletion() などトランザクション関連のイベントにコールバックを提供します。 デフォルトでは Seam はそれ自体のトランザクション同期化コンポーネントを使用します。これには同期化のコールバックが必ず正しく実行されるようトランザクションをコミットするときに Seam トランザクションコンポーネントを明示的に使用することが必要です。 Java EE 5 環境では <transaction:ejb-transaction/> を components.xml で宣言し、 コンテナが Seam の認識範囲外にトランザクションをコミットする場合に Seam 同期化のコールバックが正しく呼び出されるようにしてください。
10.3. Seam 管理永続コンテキスト リンクのコピーリンクがクリップボードにコピーされました!
EntityManager または Session のインスタンスを管理する組み込みの Seam コンポーネントです。 @In でインジェクトすることができます。
10.3.1. JPA での Seam 管理永続コンテキストの使用 リンクのコピーリンクがクリップボードにコピーされました!
components.xml 内に次のように記述します。
<persistence:managed-persistence-context name="bookingDatabase" auto-create="true" persistence-unit-jndi-name="java:/EntityManagerFactories/bookingData"/>
<persistence:managed-persistence-context name="bookingDatabase"
auto-create="true"
persistence-unit-jndi-name="java:/EntityManagerFactories/bookingData"/>
bookingDatabase という名前の Seam コンポーネントが作成され、 JNDI 名 java:/EntityManagerFactories/bookingData を持つ永続ユニット (EntityManagerFactory インスタンス) の EntityManager インスタンスの寿命を管理します。
EntityManagerFactory を JNDI にバインドする必要があります。これを行うには JBoss では、 次のプロパティ設定を persistence.xml に追加します。
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/EntityManagerFactories/bookingData"/>
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/EntityManagerFactories/bookingData"/>
EntityManager をインジェクトできます。
@In EntityManager bookingDatabase;
@In EntityManager bookingDatabase;
@TransactionAttribute(REQUIRES_NEW) をマークすると、トランザクションと永続コンテキストはこのオブジェクトでのメソッド呼び出しには伝播されないはずです。 ただし、 Seam 管理永続コンテキストは対話内のいずれのコンポーネントにも伝播されるため REQUIRES_NEW とマークされたメソッドに伝播されます。 したがって、 メソッドに REQUIRES_NEW をマークする場合は @PersistenceContext を使ってエンティティマネージャにアクセスしてください。
10.3.2. Seam 管理の Hibernate セッションの使用 リンクのコピーリンクがクリップボードにコピーされました!
components.xml で次のように記述することができます。
java:/bookingSessionFactory は hibernate.cfg.xml で指定されるセッションファクトリ名です。
注記
hibernate.transaction.flush_before_completion を常に有効にしてセッションが JTA トランザクションのコミットより先に自動的に同期されるようにしてください。
Session をインジェクトできます。
@In Session bookingDatabase;
@In Session bookingDatabase;
10.3.3. Seam 管理永続コンテキストとアトミックな対話 リンクのコピーリンクがクリップボードにコピーされました!
merge() を使用したり、 各要求の開始時にデータを再ロードしたり、 例外と格闘しなくとも (LazyInitializationException や NonUniqueObjectException)、 対話にスコープされる永続コンテキストにより複数のサーバー要求にまたがる楽観的なトランザクションをプログラムすることができます。
@Version アノテーションを付与することで楽観的ロックの使用を容易にします。
FlushModeType に対するベンダー拡張としてこの機能を提供しています。他のベンダーもすぐに同様の拡張機能を提供することが予想されます。
FlushModeType.MANUAL を指定することができます。 現在は Hibernate が永続を実現する構成要素である場合にのみ機能しますが、 他のベンダーによる同等の拡張機能もサポートする予定です。
claim オブジェクトは全対話の間、 永続コンテキストによって管理され続けます。 この claim に変更を加えることができます。
public void addPartyToClaim() {
Party party = ....;
claim.addParty(party);
}
public void addPartyToClaim() {
Party party = ....;
claim.addParty(party);
}
@End public void commitClaim() {
em.flush();
}
@End public void commitClaim() {
em.flush();
}
flushMode を MANUAL に設定することもできます。 たとえばナビゲーションルールでは以下のようになります。
<begin-conversation flush-mode="MANUAL" />
<begin-conversation flush-mode="MANUAL" />
10.4. JPA 「delegate」の使用 リンクのコピーリンクがクリップボードにコピーされました!
EntityManager インターフェースにより getDelegate() メソッドを通じてベンダー固有の API にアクセスすることができます。 Hibernate をベンダーとして使用し、 org.hibernate.Session を delegate インターフェースとして使用することをお勧めしますが、 別の JPA プロバイダを使用する必要がある場合は 「代替の JPA プロバイダの使用」 で詳細をご確認ください。
@In EntityManager entityManager;
@Create public void init() {
((Session)entityManager.getDelegate() ).enableFilter("currentVersions");
}
@In EntityManager entityManager;
@Create public void init() {
((Session)entityManager.getDelegate() ).enableFilter("currentVersions");
}
components.xml に追加することで delegate にアクセスすることもできます。
<factory name="session" scope="STATELESS" auto-create="true"
value="#{entityManager.delegate}"/>
<factory name="session" scope="STATELESS" auto-create="true"
value="#{entityManager.delegate}"/>
10.5. EJB-QL/HQL での EL の使用 リンクのコピーリンクがクリップボードにコピーされました!
@PersistenceContext でコンテナ管理永続コンテキストをインジェクトする場合は、常に Seam は EntityManager または Session オブジェクトをプロキシします。 これにより、 EL 式をクエリ文字列内で問題なく効果的に使用することができます。 たとえば、 次を見てください。
User user = em.createQuery("from User where username=#{user.username}")
.getSingleResult();
User user = em.createQuery("from User where username=#{user.username}")
.getSingleResult();
User user = em.createQuery("from User where username=:username")
.setParameter("username", user.getUsername())
.getSingleResult();
User user = em.createQuery("from User where username=:username")
.setParameter("username", user.getUsername())
.getSingleResult();
警告
User user = em.createQuery("from User where username=" + user.getUsername()).getSingleResult(); //BAD!
User user = em.createQuery("from User where username=" + user.getUsername()).getSingleResult(); //BAD!
10.6. Hibernate フィルタの使用 リンクのコピーリンクがクリップボードにコピーされました!
EntityManager や Hibernate Session が初めて作成されたときは常に有効になります (Hibernate が永続を実現する構成要素である場合にのみ使用できます)。
第11章 Seam での JSF フォーム検証 リンクのコピーリンクがクリップボードにコピーされました!
Location クラスで制約を定義するところから始めましょう。
<s:validate> を使ってモデルオブジェクトで定義される制約に対して検証を行います。
注記
@NotNull を指定してもコントロールに出現させるのに required="true" が必要なくなるというわけではありません。これは JSF 検証アーキテクチャの限界によるものです。
<s:validateAll> を使ってみます。
<s:validate> をフォーム内のすべての入力に追加します。 フォームが大きくなる場合は、 入力の手間をかなり省くことができます。
label 属性を使いラベルを定義する必要があります。
<h:inputText value="#{location.zip}" required="true" label="Zip:">
<s:validate/>
</h:inputText>
<h:inputText value="#{location.zip}" required="true" label="Zip:">
<s:validate/>
</h:inputText>
注記
<s:decorate> を使って各フォームフィールドにこのテンプレートを含ませることができます。
location.zipCode.invalid = The zip code is not valid for #{location.name}
location.zipCode.invalid = The zip code is not valid for #{location.name}
第12章 Groovy 統合 リンクのコピーリンクがクリップボードにコピーされました!
12.1. はじめに リンクのコピーリンクがクリップボードにコピーされました!
12.2. Groovy による Seam アプリケーションの記述 リンクのコピーリンクがクリップボードにコピーされました!
12.2.1. Groovy コンポーネントの記述 リンクのコピーリンクがクリップボードにコピーされました!
12.2.1.1. エンティティ リンクのコピーリンクがクリップボードにコピーされました!
例12.1 Seam アプリケーションでの Groovy の使用
hotel.getCity() でアクセスできます。 この getter や setter は Groovy のコンパイラが生成したものです。 こうした簡略構文を使えば、 エンティティコードは非常に簡潔になります。
12.2.2. Seam コンポーネント リンクのコピーリンクがクリップボードにコピーされました!
例12.2 Groovy による Seam コンポーネントの記述
12.2.3. seam-gen リンクのコピーリンクがクリップボードにコピーされました!
.groovy ファイルを src/main に置くだけです。 アクションを記述する場合には .groovy ファイルを src/hot に置くだけです。
12.3. デプロイ リンクのコピーリンクがクリップボードにコピーされました!
12.3.1. Groovy コードのデプロイ リンクのコピーリンクがクリップボードにコピーされました!
groovyc ant タスクを使用します。 コンパイルされると、 Groovy のクラスは Java クラスとまったく同じになるため、 アプリケーションサーバーはどちらも同等に扱います。これにより Groovy と Java のコードをシームレスに融合させることができます。
12.3.2. 開発時のネイティブ .groovy ファイルのデプロイ リンクのコピーリンクがクリップボードにコピーされました!
.groovy ファイルのホットデプロイをサポートしています (コンパイルしないでデプロイを行う)。 このモードは開発のみとなり、 修正 / テストの高速周期を実現します。 「Seam と増分ホットデプロイメント」 の設定方法に従って .groovy ホットデプロイメントを設定します。 Groovy コード (.groovy ファイル) を WEB-INF/dev ディレクトリにデプロイします。 アプリケーションまたはアプリケーションサーバーを再起動することなく、 GroovyBean コンポーネントは増加的にデプロイを行うようになります。
注記
.groovy ファイルのデプロイメントには通常の Seam ホットデプロイメントと同じ制約があります。
- コンポーネントは JavaBeans または GroovyBeans でなければなりません。 EJB3 Bean は使用できません。
- エンティティはホットデプロイできません。
- ホットデプロイ可能なコンポーネントは
WEB-INF/devの外部にデプロイされたクラスからは見えません。 - Seam デバックモードを有効にしなければなりません。
12.3.3. seam-gen リンクのコピーリンクがクリップボードにコピーされました!
.groovy ファイルのホットデプロイメントも含まれます。 WAR タイプのプロジェクトでは src/hot の Java と Groovy のクラス群は自動的に増分ホットデプロイメントの対象となります。 実稼働モードでは Groovy ファイルはデプロイメントの前にコンパイルされます。
examples/groovybooking には、 完全に Groovy で記述された増分ホットデプロイメントに対応する Booking デモがあります。
第13章 Seam アプリケーションフレームワーク リンクのコピーリンクがクリップボードにコピーされました!
13.1. はじめに リンクのコピーリンクがクリップボードにコピーされました!
components.xml でコンポーネントのインスタンスをインストールし、設定する方法です。 たとえば、 以下の components.xml 設定の一部では Person エンティティに対する基本的な CRUD 操作を実行する 1 コンポーネントをインストールします。
<framework:entity-home name="personHome" entity-class="eg.Person"
entity-manager="#{personDatabase}">
<framework:id>#{param.personId}</framework:id>
</framework:entity-home>
<framework:entity-home name="personHome" entity-class="eg.Person"
entity-manager="#{personDatabase}">
<framework:id>#{param.personId}</framework:id>
</framework:entity-home>
@Stateful
@Name("personHome")
public class PersonHome extends EntityHome<Person>
implements LocalPersonHome { }
@Stateful
@Name("personHome")
public class PersonHome extends EntityHome<Person>
implements LocalPersonHome { }
entityManager であってもインジェクションを使って永続コンテキストを提供 しなければなりません。
EntityHome と HibernateEntityHome、またクエリ用にEntityQuery と HibernateEntityQuery の 4 つの主要な組み込みコンポーネントを提供しています。
entityManager という名前の永続コンテキストを期待します。
13.2. Home オブジェクト リンクのコピーリンクがクリップボードにコピーされました!
Person クラスについて考えてみましょう。
personHome コンポーネントを定義するには、以下のように設定を通じて行うか
<framework:entity-home name="personHome" entity-class="eg.Person" />
<framework:entity-home name="personHome" entity-class="eg.Person" />
@Name("personHome")
public class PersonHome extends EntityHome<Person> {}
@Name("personHome")
public class PersonHome extends EntityHome<Person> {}
persist()、 remove()、 update()、 getInstance() のような動作を提供します。 remove() または update() を呼び出す前に、setId() メソッドを用いて対象のオブジェクトの識別子を設定する必要があります。
Person は person で参照できると便利なため、components.xml にその行を加えます (設定を使用している場合)。
<factory name="person" value="#{personHome.instance}"/>
<framework:entity-home name="personHome" entity-class="eg.Person" />
<factory name="person" value="#{personHome.instance}"/>
<framework:entity-home name="personHome" entity-class="eg.Person" />
PersonHome に @Factory メソッドを追加できます。
Person のエントリを作成するために必要なすべてのコードです。 データベースの既存の Person エントリを表示、更新、削除できるようにしたい場合は PersonHome にそのエントリの識別子を渡すことが必要です。 これを行うにはページパラメータの使用が適しています。
Create Person としてページが表示されます。 personId 要求パラメータに値を与えると Edit Person ページが表示されます。
Person エントリを作成しなければならない場合を考えてみましょう。これも簡単にできます。設定を使う場合は、以下のとおりです。
Country は、例えば、CountryHome という別の Home オブジェクトの管理下のオブジェクトとすることもできます。
PersonHome にメソッドを追加するだけでできるようになります。
persist()、 update()、 または remove() への呼び出し)、 Home オブジェクトは org.jboss.seam.afterTransactionSuccess イベントを引き起こします。 このイベントを監視することで元になるエンティティが変更された場合にクエリをリフレッシュすることができます。 任意のエンティティの永続化、 更新、 削除が行われたときに特定のクエリをリフレッシュしたいだけの場合は org.jboss.seam.afterTransactionSuccess.<name> を監視します (<name> がそのエンティティ名です)。
messages という名前のバンドル) にそのメッセージを定義することです。
Person_created=New person #{person.firstName} #{person.lastName} created
Person_deleted=Person #{person.firstName} #{person.lastName} deleted
Person_updated=Person #{person.firstName} #{person.lastName} updated
Person_created=New person #{person.firstName} #{person.lastName} created
Person_deleted=Person #{person.firstName} #{person.lastName} deleted
Person_updated=Person #{person.firstName} #{person.lastName} updated
13.3. Query オブジェクト リンクのコピーリンクがクリップボードにコピーされました!
Person インスタンスの全一覧が必要な場合は Query オブジェクトを以下のように使うことができます。
<framework:entity-query name="people" ejbql="select p from Person p"/>
<framework:entity-query name="people" ejbql="select p from Person p"/>
<framework:entity-query name="people" ejbql="select p from Person p"
order="lastName" max-results="20"/>
<framework:entity-query name="people" ejbql="select p from Person p"
order="lastName" max-results="20"/>
org.jboss.seam.afterTransactionSuccess イベントを監視します。
<event type="org.jboss.seam.afterTransactionSuccess">
<action execute="#{people.refresh}" />
</event>
<event type="org.jboss.seam.afterTransactionSuccess">
<action execute="#{people.refresh}" />
</event>
PersonHome で person エンティティの永続化、 更新、または削除が行われた場合にクエリをリフレッシュする場合は次のようにします。
<event type="org.jboss.seam.afterTransactionSuccess.Person">
<action execute="#{people.refresh}" />
</event>
<event type="org.jboss.seam.afterTransactionSuccess.Person">
<action execute="#{people.refresh}" />
</event>
getCountEjbql() を無効化して、結果の合計数を計算する独自の方法を実装する必要があります。
13.4. Controller オブジェクト リンクのコピーリンクがクリップボードにコピーされました!
Controller クラスとそのサブクラス (EntityController、 HibernateEntityController、 BusinessProcessController) は Seam Application Framework のオプションとなる部分です。よく使用される組み込みのコンポーネントやコンポーネントメソッドへの便利なアクセス方法を提供します。このクラスを使用するとキーストロークを節約でき、また新しいユーザーにとっては Seam に組み込まれている豊富な機能を探る素晴らしい足掛かりとなります。
RegisterAction (Seam 登録のサンプルより) は次のようになります。
第14章 Seam と JBoss Rules リンクのコピーリンクがクリップボードにコピーされました!
14.1. ルールをインストールする リンクのコピーリンクがクリップボードにコピーされました!
org.drools.RuleBase のインスタンスを使用可能にすることです。 テスト目的で、 Seam はクラスパスから静的なルール一式をコンパイルする組み込みコンポーネントを提供しています。 このコンポーネントは components.xml を使ってインストールできます。
.drl) 一式、 またはデシジョンテーブル (.xls) ファイルからルールをコンパイルし、 Seam APPLICATION コンテキストに org.drools.RuleBase のインスタンスをキャッシュします。 ルール駆動型アプリケーションには複数のルールベースのインストールが必要となる可能性が高いので留意してください。
components.xml で設定が可能です。
<drools:rule-agent name="insuranceRules"
configurationFile="/WEB-INF/deployedrules.properties" />
<drools:rule-agent name="insuranceRules"
configurationFile="/WEB-INF/deployedrules.properties" />
org.drools.WorkingMemory インスタンスを使用可能にする必要があります (各 WorkingMemory は現在の対話に関連する fact を蓄積します)。
<drools:managed-working-memory name="policyPricingWorkingMemory"
auto-create="true" rule-base="#{policyPricingRules}"/>
<drools:managed-working-memory name="policyPricingWorkingMemory"
auto-create="true" rule-base="#{policyPricingRules}"/>
ruleBase 設定プロパティでルールベースに対して policyPricingWorkingMemory を参照している点に注目してください。
14.2. Seam コンポーネントからのルールの使用 リンクのコピーリンクがクリップボードにコピーされました!
WorkingMemory を任意の Seam コンポーネントにインジェクトし、 fact をアサートしてルールを実行することができます。
14.3. jBPM プロセス定義からのルールの使用 リンクのコピーリンクがクリップボードにコピーされました!
<assertObjects> エレメントは WorkingMemory に fact としてアサートされるオブジェクトの集合または 1 オブジェクトを返す EL 式を指定します。
Assignable は assignable として、 Seam Decision オブジェクトは decision として使用可能です。 decision を処理するルールは decision.setOutcome"result") を呼び出して決定結果を確定するはずです。assignment を実行するルールは Assignable を持つ actor IDを設定するはずです。
注記
重要
第15章 セキュリティ リンクのコピーリンクがクリップボードにコピーされました!
15.1. 概要 リンクのコピーリンクがクリップボードにコピーされました!
- 認証 − あらゆるセキュリティプロバイダに対してユーザー認証を可能にする、拡張可能な JAAS ベースの認証層を提供します。
- アイデンティティ管理 − ランタイムに Seam アプリケーションのユーザーとロールを管理する API を提供します。
- 承認 − ユーザーのロール、 永続的なルールベースのパーミッション、 カスタマイズされたセキュリティロジックを簡単に実装できるプラグイン可能なパーミッションリゾルバをサポートする非常に包括的な承認フレームワークを提供します。
- パーミッション管理 − アプリケーションのセキュリティポリシーの管理を容易にする組み込みの Seam コンポーネント一式を提供します。
- CAPCHA サポート − Seam ベースのサイトに有害となる自動化ソフトウェア / スクリプトから保護するためのサポートを提供します。
15.2. セキュリティを無効にする リンクのコピーリンクがクリップボードにコピーされました!
Identity.setSecurityEnabled(false) を呼び出します。 ただし、 アプリケーションを設定したい場合は代わりに次の設定を components.xml で制御する方が便利でしょう。
- エンティティのセキュリティ
- Hibernate セキュリティインターセプタ
- Seam Security インターセプタ
- ページ単位の制約
- サーブレット API セキュリティ統合
15.3. 認証 リンクのコピーリンクがクリップボードにコピーされました!
15.3.1. 認証コンポーネントの設定 リンクのコピーリンクがクリップボードにコピーされました!
注記
SeamLoginModule) を使用します (このモジュールは余分な設定ファイルを必要とせず、 Seam 内で事前設定され同梱されています)。これにより、 使用するアプリケーションで提供されるエンティティクラスで認証メソッドを記述する、 または別のサードパーティのプロバイダ経由で認証を行うことができます。 この単純化された認証を設定するには components.xml で下記のように identity コンポーネントを設定する必要があります。
#{authenticator.authenticate} は authenticator コンポーネントの authenticate メソッドがユーザーの認証に使用されることを示すメソッドバインディングです。
15.3.2. 認証メソッドの記述 リンクのコピーリンクがクリップボードにコピーされました!
components.xml 内の identity に対して指定される authenticate-method プロパティは、SeamLoginModule で使用されるメソッドを指定してユーザー認証を行います。 このメソッドはパラメータを取らないため、 認証が成功したか失敗したかを示す Boolean を返します。 ユーザー名とパスワードは Credentials.getUsername() と Credentials.getPassword() からそれぞれ取得します (credentials コンポーネントへの参照は Identity.instance().getCredentials() から 取得可能)。 ユーザーがメンバーとなるすべてのロールは Identity.addRole() で割り当ててください。 以下に POJO コンポーネント内の認証メソッドの完全な例を示します。
User と UserRole はアプリケーション固有のエンティティ Bean です。 パラメータ roles はユーザーがメンバーとなるロールで埋められます。 たとえば、「admin」や「user」など Set にリテラル文字列値として追加されます。 ユーザー記録が見つからず NoResultException が送出される場合は、 認証メソッドは false を返して認証が失敗したことを示します。
注記
15.3.2.1. Identity.addRole() リンクのコピーリンクがクリップボードにコピーされました!
Identity.addRole() メソッドの動作は現在のセッション認証により異なります。 セッションが認証されていない場合、 addRole() は認証過程でのみ呼び出されるはずです。 ここで呼び出されると、 ロール名は事前認証されたロールの一時リストに配置されます。 認証が成功したら事前認証されたロールが「実際の」ロールとなり、 これらのロールに対する Identity.hasRole() 呼び出しは true を返します。 以下のシーケンス図に、認証過程におけるその位置付けを明確にするため 1 番目のクラスオブジェクトとして事前認証されたロールリストを示します。
Identity.addRole() を呼び出すと指定されたロールが直ちに現在のユーザーに付与されます。
15.3.2.2. セキュリティ関連のイベントにイベントオブザーバーを記述する リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.security.loginSuccessful イベントのイベントオブザーバーを以下のように記述することができます。
15.3.3. ログインフォームの記述 リンクのコピーリンクがクリップボードにコピーされました!
credentials コンポーネントは username および password のプロパティを提供し、最も一般的な認証シナリオに対応できるようになっています。 これらのプロパティはログインフォームのユーザー名とパスワードのフィールドに直接バインドされることができます。 これらのプロパティを設定した後 identity.login() を呼び出すと、 与えた資格情報でそのユーザーの認証が行われます。 簡単なログインフォームの例を以下に示します。
#{identity.logout} を呼び出すとユーザーはログアウトされます。 この動作により、 現在認証されているユーザーのセキュリティの状態を削除し、そのユーザーのセッションを無効化します。
15.3.4. 設定のまとめ リンクのコピーリンクがクリップボードにコピーされました!
- 認証メソッドを
components.xmlに設定します。 - 認証メソッドを記述します。
- ユーザーを認証できるようログインフォームを記述します。
15.3.5. Remember Me リンクのコピーリンクがクリップボードにコピーされました!
警告
rememberMe.enabled にバインドするだけです。次の例をみてください。
15.3.5.1. トークンベースの Remember Me 認証 リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.security.TokenStore インターフェースを使って独自のトークンストアを実装することも可能です。本項では JpaTokenStore 実装を使用して認証トークンをデータベーステーブル内に保存することを前提としています。
@TokenUsername と @TokenValue という特殊なアノテーションが使われています。 認証トークンを保持するエンティティにはこれらのアノテーションが必要です。
JpaTokenStore を設定します。そのために components.xml の token-class 属性を指定します。
<security:jpa-token-store
token-class="org.jboss.seam.example.seamspace.AuthenticationToken"/>
<security:jpa-token-store
token-class="org.jboss.seam.example.seamspace.AuthenticationToken"/>
components.xml に RememberMe コンポーネントを設定します。その mode は autoLogin に設定してください。
<security:remember-me mode="autoLogin"/>
<security:remember-me mode="autoLogin"/>
components.xml に以下のセクションを含めてください。
15.3.6. セキュリティ例外の処理 リンクのコピーリンクがクリップボードにコピーされました!
pages.xml を編集してもう少し見栄えのするページにリダイレクトしてください。セキュリティ API により送出される例外には主として 2 つのタイプがあります。
NotLoggedInException- ユーザーがログインすることなく制限された操作やページにアクセスしようとするとこの例外が送出されます。AuthorizationException— 既にログインしているユーザーがアクセス許可を持たない制限された操作やページにアクセスしようとしたときにのみこの例外が送出されます。
NotLoggedInException の場合、 ユーザーをログインページかユーザー登録ページにリダイレクトしてログイン操作を行えるようにすることをお勧めします。 AuthorizationException の場合は、 ユーザーをエラーページにリダイレクトした方が良いでしょう。 以下の例では、 この 2 つのセキュリティ例外をリダイレクトする pages.xml ファイルを示しています。
15.3.7. ログインのリダイレクト リンクのコピーリンクがクリップボードにコピーされました!
注記
components.xml に追加すると、 ログインせずに行われた制限ビューへのアクセス試行は記憶されます。 ログインに成功すると、ユーザーは当初の要求時に存在したページパラメータを持つ当該ビューにリダイレクトされます。
注記
authenticate() メソッドの中で対話を終了させないでください。
15.3.8. HTTP 認証 リンクのコピーリンクがクリップボードにコピーされました!
components.xml で authentication-filter コンポーネントを有効にする必要があります。
<web:authentication-filter url-pattern="*.seam" auth-type="basic"/>
<web:authentication-filter url-pattern="*.seam" auth-type="basic"/>
auth-type を basic に設定します。 ダイジェスト認証を有効にするには、 digest に設定します。 ダイジェスト認証を使用する場合には key と realm も設定する必要があります。
<web:authentication-filter url-pattern="*.seam" auth-type="digest"
key="AA3JK34aSDlkj" realm="My App"/>
<web:authentication-filter url-pattern="*.seam" auth-type="digest"
key="AA3JK34aSDlkj" realm="My App"/>
key は任意の文字列です。 realm はユーザーが認証される時にユーザーに提供される認証レルム名です。
15.3.8.1. ダイジェスト認証の記述 リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.security.digest.DigestAuthenticator 抽象クラスを拡張して、validatePassword() メソッドを使用しユーザーのプレーンテキストのパスワードとダイジェスト要求を照合する必要があります。 以下はコード例です。
15.3.9. 高度な認証機能 リンクのコピーリンクがクリップボードにコピーされました!
15.3.9.1. 使用しているコンテナの JAAS の設定 リンクのコピーリンクがクリップボードにコピーされました!
components.xml に jaas-config-name プロパティを追加してシステムのデフォルトの JAAS 設定を使用することができます。 例として、 JBoss AS を使用していて otherポリシー (JBoss AS 提供の UsersRolesLoginModule ログインモジュールを使用する) を使用したい場合には、 components.xml は以下のようになります。
<security:identity jaas-config-name="other"/>
<security:identity jaas-config-name="other"/>
15.4. アイデンティティ管理 リンクのコピーリンクがクリップボードにコピーされました!
identityManager コンポーネントです。それは、ユーザーの作成、 変更および削除、 ロールの許可とその取り消し、 パスワードの変更、 ユーザーアカウントの有効化と無効化、 ユーザーの認証、 ユーザーとロールの一覧表示などを行うための全メソッドを提供します。
identityManager に IdentityStore を 1 つ以上設定する必要があります。 これらのコンポーネントがバックエンドのセキュリティプロバイダと連携して動作します。
15.4.1. IdentityManager の設定 リンクのコピーリンクがクリップボードにコピーされました!
identityManager コンポーネントにより、認証および承認に対して別々のアイデンティティストアを設定することができます。 つまり、 ユーザーを任意のアイデンティティストアに対して認証させることができますが (LDAP ディレクトリなど)、そのユーザーのロールは別のアイデンティティストア (リレーショナルデータベースなど) からロードさせます。
IdentityStore 実装を提供しています。 デフォルトとなる JpaIdentityStore はリレーショナルデータベースを使用してユーザーとロールの情報を格納します。 もうひとつの実装は LdapIdentityStore で、LDAP ディレクトリを使用してユーザーとロールを格納します。
identityManager コンポーネントにはidentityStore と roleIdentityStore の 2 つの設定可能なプロパティがあります。 これらプロパティの値は IdentityStore インターフェースを使って Seam コンポーネントを参照する EL 式でなければなりません。 特に設定しないとデフォルトが使用されます (JpaIdentityStore)。 また、 identityStore プロパティのみを設定した場合には roleIdentityStore に同じ値が使用されます。 例えば、 components.xml にある次のエントリは identityManager がユーザー関連の操作およびロール関連の操作の両方に LdapIdentityStore を使用するよう設定します。
<security:identity-manager identity-store="#{ldapIdentityStore}"/>
<security:identity-manager identity-store="#{ldapIdentityStore}"/>
LdapIdentityStore を、 またロールに関する処理には JpaIdentityStore を使用するよう identityManager を設定しています。
<security:identity-manager identity-store="#{ldapIdentityStore}"
role-identity-store="#{jpaIdentityStore}"/>
<security:identity-manager identity-store="#{ldapIdentityStore}"
role-identity-store="#{jpaIdentityStore}"/>
15.4.2. JpaIdentityStore リンクのコピーリンクがクリップボードにコピーされました!
15.4.2.1. JpaIdentityStore の設定 リンクのコピーリンクがクリップボードにコピーされました!
JpaIdentityStore を使用する前に、 user-class と role-class の両方を設定しておく必要があります。 これらのプロパティはユーザーとロールそれぞれの記録保存に使用するエンティティクラス郡を参照します。 以下の例では、 SeamSpace のサンプルにある components.xml ファイルを示しています。
15.4.2.2. エンティティの設定 リンクのコピーリンクがクリップボードにコピーされました!
|
アノテーション
|
ステータス
|
詳細
|
|---|---|---|
@UserPrincipal
|
必須
|
このアノテーションはユーザーのユーザー名を含むフィールドまたはメソッドをマークします。
|
@UserPassword
|
必須
|
このアノテーションはユーザーのパスワードを含むフィールドまたはメソッドをマークします。パスワードハッシュに
hash アルゴリズムを指定することができます。hash に指定できる値には md5、sha、none があります。たとえば以下のとおりです。
@UserPassword(hash = "md5")
public String getPasswordHash() {
return passwordHash;
}
他のハッシュアルゴリズムを実装する必要がある場合は、
PasswordHash を拡張することができます。
|
@UserFirstName
|
オプション
|
このアノテーションはユーザーの名前を含むフィールドまたはメソッドをマークします。
|
@UserLastName
|
オプション
|
このアノテーションはユーザーの姓を含むフィールドあるいはメソッドをマークします。
|
@UserEnabled
|
オプション
|
このアノテーションは有効なユーザーステータスを含むフィールドまたはメソッドをマークします。これは Boolean プロパティとなるはずです。このアノテーションが存在しないと、すべてのユーザーアカウントは有効であるとみなされます。
|
@UserRoles
|
必須
|
このアノテーションはユーザーのロールを含むフィールドまたはメソッドをマークします。このプロパティの詳細については後ほど記載します。
|
|
アノテーション
|
ステータス
|
詳細
|
|---|---|---|
@RoleName
|
必須
|
このアノテーションはロール名を含むフィールドまたはメソッドをマークします。
|
@RoleGroups
|
オプション
|
このアノテーションはロールのグループメンバーシップを含むフィールドまたはメソッドをマークします。
|
@RoleConditional
|
オプション
|
このアノテーションはロールが条件付きか否かを示すフィールドまたはメソッドをマークします。条件付きロールについては本章の後半で説明します。
|
15.4.2.3. エンティティ Bean の例 リンクのコピーリンクがクリップボードにコピーされました!
JpaIdentityStore は、ユーザーとロールのテーブルのデーターベーススキーマ設計に関してはできるだけ柔軟につくられています。本項では、ユーザーとロール記録を保持することが可能なデータベースのスキーマについて見ていきます。
15.4.2.3.1. 最小限のスキーマの例 リンクのコピーリンクがクリップボードにコピーされました!
UserRoles を使って many-to-many の関係でシンプルなユーザーとロールのテーブルがリンクされています。
15.4.2.3.2. 複雑なスキーマの例 リンクのコピーリンクがクリップボードにコピーされました!
15.4.2.4. JpaIdentityStore イベント リンクのコピーリンクがクリップボードにコピーされました!
JpaIdentityStore を IdentityManager で使用する場合、 特定の IdentityManager メソッドが呼び出されるといくつかのイベントが発生します。
15.4.2.4.1. JpaIdentityStore.EVENT_PRE_PERSIST_USER リンクのコピーリンクがクリップボードにコピーされました!
IdentityManager.createUser() の呼び出しに応じて発生します。 ユーザーエンティティがデータベースに対して永続化される直前に、 このイベントが発生してンティティインスタンスをイベントパラメータとして渡します。 このエンティティは JpaIdentityStore に設定した user-class のインスタンスです。
createUser() 機能の一部ではないエンティティフィールドの値を設定する場合にはオブザーバーが便利です。
15.4.2.4.2. JpaIdentityStore.EVENT_USER_CREATED リンクのコピーリンクがクリップボードにコピーされました!
IdentityManager.createUser() の呼び出しにも応じて発生します。 ただし、 このイベントはユーザーエンティティがデータベースに対してすでに永続化されてから発生します。 EVENT_PRE_PERSIST_USER イベントと同様、 イベントパラメータとしてエンティティのインスタンスを渡します。 連絡先の詳細情報の記録や他のユーザー固有データなど、ユーザーエンティティを参照する他のエンティティを永続化する必要がある場合にこのイベントを監視すると便利です。
15.4.2.4.3. JpaIdentityStore.EVENT_USER_AUTHENTICATED リンクのコピーリンクがクリップボードにコピーされました!
IdentityManager.authenticate() を呼び出すと発生します。 このイベントはエンティティインスタンスをイベントパラメータとして渡すため、 認証されるユーザーエンティティの追加のプロパティを読み取る場合に便利です。
15.4.3. LdapIdentityStore リンクのコピーリンクがクリップボードにコピーされました!
15.4.3.1. LdapIdentiyStore の設定 リンクのコピーリンクがクリップボードにコピーされました!
LdapIdentityStore に対して components.xml で設定できるプロパティを示します。
|
プロパティ
|
デフォルト値
|
詳細
|
|---|---|---|
server-address
| localhost
|
LDAP サーバーのアドレスです。
|
server-port
| 389
|
LDAP サーバーがリッスンしているポート番号です。
|
user-context-DN
| ou=Person,dc=acme,dc=com
|
ユーザーレコードを含むコンテキストの識別名 (DN) です。
|
user-DN-prefix
| uid=
|
この値は username の前に置かれ、ユーザーレコードを検索します。
|
user-DN-suffix
| ,ou=Person,dc=acme,dc=com
|
この値は username の後ろに追加され、ユーザーレコードを検索します。
|
role-context-DN
| ou=Role,dc=acme,dc=com
|
ロールレコードを含むコンテキストの識別名 (DN) です。
|
role-DN-prefix
| cn=
|
この値はロール名の前に置かれ、ロール記録を検索する DN を形成します。
|
role-DN-suffix
| ,ou=Roles,dc=acme,dc=com
|
この値はロール名の後ろに追加され、 ロール記録を検索する DN を形成します。
|
bind-DN
| cn=Manager,dc=acme,dc=com
|
LDAP サーバーとバインドするために使用するコンテキストです。
|
bind-credentials
| secret
|
LDAP サーバーとバインドするために使用される資格情報 (パスワード) です。
|
user-role-attribute
| roles
|
ユーザーがメンバーであるロールの一覧を含むユーザーレコードの属性名です。
|
role-attribute-is-DN
| true
|
この Boolean プロパティはユーザーレコードのロール属性自体が識別名か否かを示しています。
|
user-name-attribute
| uid
|
ユーザー名を含むユーザーレコードの属性を示します。
|
user-password-attribute
| userPassword
|
ユーザーのパスワードを含むユーザーレコードの属性を示します。
|
first-name-attribute
| null
|
ユーザーの名前を含むユーザーレコードの属性を示します。
|
last-name-attribute
| sn
|
ユーザーの姓を含むユーザーレコードの属性を示します。
|
full-name-attribute
| cn
|
ユーザーのフルネームを含むユーザーレコードの属性を示します。
|
enabled-attribute
| null
|
ユーザーが有効であるかを決定するユーザーレコードの属性を示します。
|
role-name-attribute
| cn
|
ロール名を含むロール記録の属性を示します。
|
object-class-attribute
| objectClass
|
ディレクトリ内のオブジェクトのクラスを決定する属性を示します。
|
role-object-classes
| organizationalRole
|
新しいロール記録の作成のためのオブジェクトクラスの配列です。
|
user-object-classes
| person,uidObject
|
新しいユーザーレコード作成のためのオブジェクトクラスの配列です。
|
15.4.3.2. LdapIdentityStore の設定例 リンクのコピーリンクがクリップボードにコピーされました!
directory.mycompany.com で動作している LDAP ディレクトリに LdapIdentityStore を設定する方法を示しています。 ユーザーはこのディレクトリ内に ou=Person,dc=mycompany,dc=com というコンテキストで保存され、 uid 属性で識別されます (そのユーザー名に対応する)。 ロールはロール用のコンテキスト ou=Roles,dc=mycompany,dc=com に保存され、 ユーザーのエントリから roles 属性を通じて参照されます。 ロールのエントリはロール名に対応するロールの一般名 (cn 属性) で識別されます。 この例では、 ユーザーは enabled 属性の値を false に設定すると無効にすることができます。
15.4.4. 独自の IdentityStore の記述 リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.security.management.IdentityStore インターフェースを実装するクラスひとつのみです。
IdentityStore は JavaDoc を参照してください。
15.4.5. アイデンティティ管理による認証 リンクのコピーリンクがクリップボードにコピーされました!
components.xml の identity 設定から authenticator-method を省略するだけで、 特別な設定をすることなく SeamLoginModule は IdentityManager を使用してアプリケーションのユーザー認証を行います。
15.4.6. IdentityManager の使用 リンクのコピーリンクがクリップボードにコピーされました!
IdentityManager へのアクセス方法は 2 通りあります。 Seam コンポーネントにインジェクトする方法は次のとおりです。
@In IdentityManager identityManager;
@In IdentityManager identityManager;
instance() メソッド経由によるアクセス方法は以下のとおりです。
IdentityManager identityManager = IdentityManager.instance();
IdentityManager identityManager = IdentityManager.instance();
IdentityManager のAPIのメソッドを示します。
|
メソッド
|
戻り値
|
詳細
|
|---|---|---|
createUser(String name, String password)
| boolean
|
指定された名前とパスワードで新規ユーザーのアカウントを作成します。成功すれば
true を、しなければ false を返します。
|
deleteUser(String name)
| boolean
|
指定された名前のユーザーアカウントを削除します。 成功すれば
true を、しなければ false を返します。
|
createRole(String role)
| boolean
|
指定された名前の新しいロールを作成します。 成功すれば
true を、しなければ false を返します。
|
deleteRole(String name)
| boolean
|
指定された名前のロールを削除します。 成功すれば
true を、しなければ false を返します。
|
enableUser(String name)
| boolean
|
指定された名前のユーザーアカウントを有効にします。有効でないアカウントは認証できません。 成功すれば
true を、しなければ false を返します。
|
disableUser(String name)
| boolean
|
指定された名前のユーザーアカウントを無効にします。成功すれば
true を、しなければ false を返します。
|
changePassword(String name, String password)
| boolean
|
指定された名前のユーザーアカウントのパスワードを変更します。 成功すれば
true を、しなければ false を返します。
|
isUserEnabled(String name)
| boolean
|
指定されたユーザーアカウントが有効であれば
true を、これ以外は false を返します。
|
grantRole(String name, String role)
| boolean
|
指定ロールを指定したユーザーまたはロールに付与します。 ロールを付与するには、 そのロールが既に存在している必要があります。 ロールの付与が成功した場合には
true を返し、 そのロールがユーザーに既に付与されていた場合には false を返します。
|
revokeRole(String name, String role)
| boolean
|
特定のユーザーまたはロールから指定したロールを取り消します。ユーザーが当該のロールのメンバーであり、かつ取り消しが成功した場合には
true を返し、ユーザーが当該ロールのメンバーでなければ false を返します。
|
userExists(String name)
| boolean
|
指定ユーザーが存在すれば
true を、 存在していなければ false を返します。
|
listUsers()
| List
|
英数字順にソートされたすべてのユーザー名の一覧を返します。
|
listUsers(String filter)
| List
|
指定されたフィルタパラメータでフィルタしたユーザー名のリストを英数字順にソートして返します
|
listRoles()
| List
|
すべてのロール名の一覧を返します。
|
getGrantedRoles(String name)
| List
|
指定されたユーザー名に明示的に付与された全ロールの一覧を返します。
|
getImpliedRoles(String name)
| List
|
指定されたユーザー名に対して暗示的に付与されている全ロールの一覧を返します。 暗示的に付与されているロールとは、ユーザーに直接付与されたロールではなく、 ユーザーがメンバーとなるロールに対して付与されたロールなどです。 例えば、
admin ロールが user ロールのメンバーであり、 ユーザーが admin ロールのメンバーであった場合、 このユーザーの暗示的なロールは admin ロールと user ロールの両方になります。
|
authenticate(String name, String password)
| boolean
|
設定された Identity Store を使ってユーザー名とパスワードを認証します。 認証が成功すれば
true を、失敗すれば false を返します。認証が成功しても、このメソッドの戻り値以外は何も変化しませんし、Identity コンポーネントの状態も変化しません。適切に Seam にログインするには Identity.login() を使用する必要があります。
|
addRoleToGroup(String role, String group)
| boolean
|
特定のロールを指定したグループのメンバーとして追加します。成功すれば true を返します。
|
removeRoleFromGroup(String role, String group)
| boolean
|
指定されたロールを指定されたグループから削除します。成功すれば true を返します。
|
listRoles()
| List
|
すべてのロール名を一覧表示します。
|
IdentityManager 内の各メソッドに対するパーミッション要件を示します。 以下に記載されるパーミッションターゲットはリテラル文字列値です。
|
メソッド
|
パーミッションターゲット
|
パーミッションのアクション
|
|---|---|---|
createUser()
| seam.user
| create
|
deleteUser()
| seam.user
| delete
|
createRole()
| seam.role
| create
|
deleteRole()
| seam.role
| delete
|
enableUser()
| seam.user
| update
|
disableUser()
| seam.user
| update
|
changePassword()
| seam.user
| update
|
isUserEnabled()
| seam.user
| read
|
grantRole()
| seam.user
| update
|
revokeRole()
| seam.user
| update
|
userExists()
| seam.user
| read
|
listUsers()
| seam.user
| read
|
listRoles()
| seam.role
| read
|
addRoleToGroup()
| seam.role
| update
|
removeRoleFromGroup()
| seam.role
| update
|
admin ロールの全メンバーにアイデンティティ管理関連の全メソッドへのアクセス権を許可する一連のセキュリティルールの例を示しています。
15.5. エラーメッセージ リンクのコピーリンクがクリップボードにコピーされました!
message.properties リソースファイルで指定するメッセージキーを一覧表示します。 特定のメッセージを隠す場合は、キー (値が空白となる) をリソースファイルに追加します。
|
メッセージキー
|
詳細
|
|---|---|
org.jboss.seam.loginSuccessful
|
このメッセージは、セキュリティ API を通してユーザーのログインが成功した場合に生成されます。
|
org.jboss.seam.loginFailed
|
このメッセージは、正しくないユーザー名またはパスワードを入力したか、何らかの認証のエラーによりユーザーがログインに失敗したときに生成されます。
|
org.jboss.seam.NotLoggedIn
|
このメッセージは、セキュリティチェックが必要な操作の実行またはページへのアクセスをユーザーが試行し、現在認証されていない場合に生成されます。
|
org.jboss.seam.AlreadyLoggedIn
|
このメッセージは、既に認証されたユーザーが再度ログインを試みた時に生成されます。
|
15.6. 承認 リンクのコピーリンクがクリップボードにコピーされました!
components.xml ファイルを設定する必要があるかもしれません。 前述の「設定」の項を参照してください。
15.6.1. 核となる概念 リンクのコピーリンクがクリップボードにコピーされました!
15.6.1.1. ロールとは リンクのコピーリンクがクリップボードにコピーされました!
15.6.1.2. パーミッションとは? リンクのコピーリンクがクリップボードにコピーされました!
target:action という形式で受信者を省略して表示されています。 実際には受信者は常に必要です。
15.6.2. コンポーネントをセキュアにする リンクのコピーリンクがクリップボードにコピーされました!
@Restrict アノテーションから始めましょう。
注記
@Restrict アノテーションはセキュリティコンポーネントに対してパワフルで柔軟なメソッドですが、EL 式に対応できません。 したがって、 コンパイル時の安全性のためタイプセーフと同等の方法を使用することをお勧めします (本章後半に記載)。
15.6.2.1. @Restrict アノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Restrict アノテーションにより Seam のコンポーネントはクラスあるいはメソッドいずれかのレベルでの安全化を図ることができます。 メソッドとその宣言クラスの両方に @Restrict アノテーションを付与すると、 メソッドの制限が優先されるためクラスの制限は適用されません。 メソッド呼び出しがセキュリティチェックに失敗した場合には、 Identity.checkRestriction() のコントラクトに応じて例外が送出されます (Inline Restriction については本項の後半を参照)。 コンポーネントクラス自体での @Restrict は、 そのメソッドそれぞれに @Restrict を追加したのと同じことになります。
@Restrict は component:methodName のパーミッションチェックを暗示します。 次のコンポーネントメソッドの例を見てみましょう。
account:delete は、delete() メソッドを呼び出すために必要な暗黙権限です。これは @Restrict("#{s:hasPermission('account','delete')}") と記述するのと同等です。 別の例についても見てみます。
@Restrict アノテーションが付与されています。 つまり @Restrict アノテーションを上書きしないメソッドはすべて暗黙のパーミッションチェックが必要になります。 この例の場合、 insert() メソッドには account:insert のパーミッションが必要となり、 delete() メソッドにはユーザーが admin ロールのメンバーであることが必要となります。
#{s:hasRole()} 式について見てみましょう。 s:hasRole も s:hasPermission も EL 式であり、 Identity クラスの同様の名前のメソッドに委任します。 こうした関数は EL 式内でセキュリティ API 全体に渡り使用することができます。
@Restrict アノテーションの値は Seam コンテキスト中のいずれのオブジェクトでも参照することができるようになります。 特定のオブジェクトのインスタンスのパーミッションをチェックする場合に非常に有効な方法です。 下の例を見てみましょう。
hasPermission() 関数呼び出しは selectedAccout を参照しています。 この変数の値は Seam コンテキスト中で検索され、 Identity 内の hasPermission() メソッドに渡されます。 これにより特定の Account オブジェクトの変更に要されるパーミッションをユーザーが持っているかどうかを判断します。
15.6.2.2. インラインによる制約 リンクのコピーリンクがクリップボードにコピーされました!
@Restrict アノテーションを使わずにコードでセキュリティチェックを行う必要がある場合があります。 この様な場合には、 以下のように Identity.checkRestriction() を使ってセキュリティ式を評価することで行います。
public void deleteCustomer() {
Identity.instance().checkRestriction("#{s:hasPermission(selectedCustomer,
'delete')}");
}
public void deleteCustomer() {
Identity.instance().checkRestriction("#{s:hasPermission(selectedCustomer,
'delete')}");
}
true に評価しない場合は 2 種類の例外のうちいずれかが発生します。 ユーザーがログインしていなかった場合は NotLoggedInException が送出されます。 ユーザーがログインしている場合は AuthorizationException が送出されます。
hasRole() や hasPermission() のメソッドを呼び出すこともできます。
15.6.3. ユーザーインターフェースのセキュリティ リンクのコピーリンクがクリップボードにコピーされました!
identity.isLoggedIn() プロパティで次のように記述することができます。
<h:form class="loginForm" rendered="#{not identity.loggedIn}">
<h:form class="loginForm" rendered="#{not identity.loggedIn}">
manager ロールを持っているユーザーだけがアクセス可能な操作をいくつか持たせたいとします。このような場合の 1 つの方法として次のように記述することができます。
<h:outputLink action="#{reports.listManagerReports}"
rendered="#{s:hasRole('manager')}"> Manager Reports
</h:outputLink>
<h:outputLink action="#{reports.listManagerReports}"
rendered="#{s:hasRole('manager')}"> Manager Reports
</h:outputLink>
manager ロールのメンバーでなければ outputLink は表示されません。 rendered 属性は一般に制御そのものに使われたり、 前後にある <s:div> や <s:span> 制御で使われます。
h:dataTable コントロールがあり、 特定の権限を持つユーザーだけにその記録に操作リンクを表示させたいとします。 s:hasPermission EL 関数によりオブジェクトパラメータを使ってユーザーがそのオブジェクトに対して必要なパーミッションを持っているかどうかを判断することができます。 安全なリンクを持つ dataTable は次のようになります。
15.6.4. ページ単位のセキュリティ リンクのコピーリンクがクリップボードにコピーされました!
pages.xml ファイルが必要になります。 ページセキュリティの設定は簡単です。 保護したい page のエレメントに <restrict/> エレメントを含ませるだけです。 restrict エレメントで明示的な制限が指定されていない場合、 Faces 以外 (GET) の要求によるアクセスには暗黙的な /viewId.xhtml:render パーミッションが必要となり、 また JSF ポストバック (フォームのサブミッション) がそのページから発生する場合には /viewId.xhtml:restore パーミッションが必要となります。 これ以外は、 指定した制限は標準のセキュリティ式で評価が行われます。 以下にいくつかの例を示します。
<page view-id="/settings.xhtml"> <restrict/> </page>
<page view-id="/settings.xhtml">
<restrict/>
</page>
/settings.xhtml:render の暗黙のパーミッションを必要とし、 Faces 要求には /settings.xhtml:restore の暗黙のパーミッションが必要となります。
<page view-id="/reports.xhtml">
<restrict>#{s:hasRole('admin')}</restrict>
</page>
<page view-id="/reports.xhtml">
<restrict>#{s:hasRole('admin')}</restrict>
</page>
admin ロールのメンバーであることを必要とします。
15.6.5. エンティティをセキュアにする リンクのコピーリンクがクリップボードにコピーされました!
@Restrict アノテーションを付与します。
@Restrict アノテーションに式が指定されていない場合、 デフォルトの操作は entity:action のパーミッションチェックとなります。 パーミッションの対象はエンティティのインスタンスで、 action は read、 insert、 update、 delete のいずれかになります。
@Restrict アノテーションを付与して特定の操作を制約することもできます。
@PostLoad− エンティティのインスタンスがデータベースからロードされた後に呼び出されます。 このメソッドはreadパーミッションの設定に使用します。@PrePersist− エンティティの新しいインスタンスが挿入される前に呼び出されます。 このメソッドはinsertパーミッションの設定に使用します。@PreUpdate− エンティティが更新される前に呼び出されます。 このメソッドはupdateパーミッションの設定に使用します。@PreRemove− エンティティが削除される前に呼び出されます。 このメソッドはdeleteパーミッションの設定に使用します。
insert の動作に対してセキュリティチェックを行うようエンティティを設定する方法を以下の例に示します。 メソッドは何も操作を行う必要はなく、重要なのはアノテーションが正しく付与されていることです。
@PrePersist
@Restrict
public void prePersist() {}
@PrePersist
@Restrict
public void prePersist() {}
注記
/META-INF/orm.xml にコールバックメソッドを指定することもできます。
Customer の prePersist() メソッドに @Restrict アノテーションを付与する必要があります。
MemberBlog 記録を挿入できるパーミッションを持っているかどうかを確認します。 チェックが行われるエンティティはワーキングメモリに自動的に挿入されます (この例の場合は MemberBlog)。
Principal ファクトで示される) がブログのエントリを作成したメンバーの名前と一致すると memberBlog:insert パーミッションを付与します。 principal: Principal() の構造は変数のバインディングです。 認証中にワーキングメモリに配置された Principal オブジェクトのインスタンスをバインドし、 それを principal という変数に割り当てます。 変数のバインディングにより、 次の行のような他の場所で変数の参照が可能になり、 メンバーの名前を Principal の名前と比較します。 詳細は JBoss Rules のドキュメントを参照してください。
15.6.5.1. JPA でのエンティティセキュリティ リンクのコピーリンクがクリップボードにコピーされました!
EntityListener を使って行われます。 次の META-INF/orm.xml ファイルでこのリスナーをインストールします。
15.6.5.2. 管理 Hibernate セッションによるエンティティのセキュリティ リンクのコピーリンクがクリップボードにコピーされました!
SessionFactory を使用し、アノテーションまたは orm.xml を使用している場合には、エンティティセキュリティ機能を使用するための特別な変更は必要はありません。
15.6.6. タイプセーフなパーミッションのアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Restrict に対する代替のアノテーションをいくつか提供しています。 異なる方法で任意の EL 式に対応し、 コンパイルタイムの安全性が向上します。
org.jboss.seam.annotations.security パッケージで提供されています。
- @Insert
- @Read
- @Update
- @Delete
@Insert(Customer.class)
public void createCustomer() { ... }
@Insert(Customer.class)
public void createCustomer() { ... }
Customer オブジェクトを作成するパーミッションを有していることを確認します。 パーミッションチェックの対象は Customer.class (実際の java.lang.Class インスタンス自体) となり、 操作はアノテーション名の小文字表記です。この例では insert です。
public void updateCustomer(@Update Customer customer) {
...
}
public void updateCustomer(@Update Customer customer) {
...
}
@PermissionCheck アノテーションを付与するだけです。 例を示します。
@PermissionCheck アノテーション内にその値を指定することができます。
@PermissionCheck("upgrade")
@PermissionCheck("upgrade")
15.6.7. タイプセーフなロールのアノテーション リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.annotations.security.Admin)。 admin ロール (アプリケーションによってこのロールがサポートされている限り) に属しているユーザーに対して特定のメソッドのアクセスを制限します。 独自のロールアノテーションを作成するためは、 以下の例のように org.jboss.seam.annotations.security.RoleCheck メタアノテーションを付与します。
@User アノテーションを付与されるメソッドはすべて自動的にインターセプトされます。 ユーザーは該当するロール名のメンバーシップについてチェックされます (アノテーション名の小文字部分、 この場合は user)。
15.6.8. パーミッションの承認モデル リンクのコピーリンクがクリップボードにコピーされました!
15.6.8.1. PermissionResolver リンクのコピーリンクがクリップボードにコピーされました!
PermissionResolver の実装を提供しています。 詳細については本章の後半に記載します。
RuleBasedPermissionResolver− Drools を使ってルールベースのパーミッションチェックを解決します。PersistentPermissionResolver− リレーショナルデータベースなど永続的なストアにオブジェクトのパーミッションを保存します。
15.6.8.1.1. 独自の PermissionResolver の記述 リンクのコピーリンクがクリップボードにコピーされました!
PermissionResolver インターフェースは実装しなければならない 2 種類のメソッドを定義します。 PermissionResolver を Seam プロジェクトにデプロイする場合、 デプロイ時に自動的にスキャンされてからデフォルトの ResolverChain で登録されます。
|
戻り値のタイプ
|
メソッド
|
詳細
|
|---|---|---|
boolean
| hasPermission(Object target, String action)
|
このメソッドは現在認証済みのユーザー (
Identity.getPrincipal() への呼び出しで取得) が target と action のパラメータで指定されるパーミッションを持っているかどうかを解決します。 ユーザーが指定パーミッションを持っている場合は true を、 持っていない場合は false を返します。
|
void
| filterSetByAction(Set<Object> targets, String action)
|
このメソッドは、 同じ
action パラメータ値を持つ hasPermission() メソッドに渡されると true を返す指定セットからオブジェクトを削除します。
|
注記
PermissionResolver の実装はいくつかの制約に順守していなければなりません。 まず、 セッションスコープより粒度の細かい状態は含むことはできず、 コンポーネント自体がアプリケーションスコープまたはセッションスコープのいずれかになるはずです。 次に複数のスレッドから同時にアクセスされる可能性があるため、依存インジェクションを使用してはいけません。 最適なパフォーマンスを得るには @BypassInterceptors アノテーションを付与して Seam のインターセプタスタックをすべて一緒に迂回することをお勧めします。
15.6.8.2. ResolverChain リンクのコピーリンクがクリップボードにコピーされました!
ResolverChain には順序つき一覧の PermissionResolver が含まれ、 特定のオブジェクトクラスやパーミッション対象に対してオブジェクトのパーミッションを解決します。
ResolverChain にはアプリケーションのデプロイメント時に見つかったすべてのパーミッションリゾルバが含まれます。 デフォルトの ResolverChain が作成されると org.jboss.seam.security.defaultResolverChainCreated イベントが発生します (また、 ResolverChain インスタンスがイベントパラメータとして渡されます)。 これによりデプロイメント時には見つからなかったリゾルバの追加、 またはチェーン内にあるリゾルバの並び替えや削除ができるようになります。
s:hasPermission EL 式などのソースから、または Identity.checkPermission への API 呼び出しにより発生することができます。
- 1. パーミッションチェックが開始され (コードまたは EL 式のいずれかにより)、 これにより
Identity.hasPermission()への呼び出しが行われます。 - 1.1.
IdentityはPermissionMapper.resolvePermission()を呼び出し、解決されるパーミッションを渡します。 - 1.1.1.
PermissionMapperはクラスによりキー付けされたResolverChainインスタンスのMapを維持します。 このマップを使ってパーミッションの対象オブジェクトに正しいResolverChainを検索します。 適切なResolverChainが見つかると、ResolverChain.getResolvers()を呼び出してそれが含むPermissionResolverの一覧を読み出します。 - 1.1.2.
ResolverChain内の各PermissionResolverに対して、PermissionMapperはそのhasPermission()メソッドを呼び出し、チェックすべきパーミッションインスタンスを渡します。PermissionResolverがtrueを返す場合はパーミッションチェックが成功しているため、PermissionMapperもIdentityにtrueを返します。 いずれのPermissionResolverもtrueを返さなければパーミッションチェックは失敗したことになります。
15.6.9. RuleBasedPermissionResolver リンクのコピーリンクがクリップボードにコピーされました!
15.6.9.1. 要件 リンクのコピーリンクがクリップボードにコピーされました!
JAR ファイルの配信がプロジェクトで必要となります。
- drools-api.jar
- drools-compiler.jar
- drools-core.jar
- janino.jar
- antlr-runtime.jar
- mvel2.jar
15.6.9.2. 設定 リンクのコピーリンクがクリップボードにコピーされました!
RuleBasedPermissionResolver の設定には、components.xml で Drools のルールベースがまず設定されていることが必要です。 以下の例のように、デフォルトではルールベースに securityRules という名前が付けられていることが期待されます。
RuleBasedPermissionResolver の security-rules プロパティを指定することで上書きすることができます。
<security:rule-based-permission-resolver
security-rules="#{prodSecurityRules}"/>
<security:rule-based-permission-resolver
security-rules="#{prodSecurityRules}"/>
RuleBase コンポーネントを設定したら、 次にセキュリティルールを記述します。
15.6.9.3. セキュリティルールの記述 リンクのコピーリンクがクリップボードにコピーされました!
/META-INF ディレクトリ内に新しいルールファイルを作成することです。 このファイルは security.drl のような名前が付けられるはずですが、components.xml で対応するよう設定されていればどのような名前でも構いません。
PermissionCheck クラスと Role クラスに関するいくつかのインポート文があります。 これらのインポート文は使用するルールがこれらのクラスを参照することをルールエンジンに伝えます。
CanUserDeleteCustomers がルールの名前で、 顧客記録の削除をユーザーが許可されているかどうかのチェックに使用されます。
when セクションで表されます。 RHS はルールの動作セクションまたは結果になり、 LHS にある条件がすべて満たされた場合にのみ実行されます。 RHS は then セクションで表されます。 ルールの最後は end 行で表されます。
c: PermissionCheck(target == "customer", action == "delete")
c: PermissionCheck(target == "customer", action == "delete")
customer と同じ target プロパティと delete と同じ action プロパティを持つ PermissionCheck オブジェクトがなければならないことを示しています。
hasPermission() メソッドが呼び出されるたび、 仮の PermissionCheck オブジェクトまたは ファクト がワーキングメモリに挿入されます。 この PermissionCheck はチェックされるパーミッションに正確に対応するため、 hasPermission("account", "create") を呼び出すと 「account」と同じ target と「create」と同じ action を持つ PermissionCheck オブジェクトがパーミッションチェックの間にワーキングメモリに挿入されます。
PermissionCheck ファクトの他に、 認証済みユーザーがメンバーとなるそれぞれのロールに org.jboss.seam.security.Role ファクトがあります。 これらの Role ファクトは、各パーミッションチェックの開始時にユーザーの認証済みロールと同期されます。結果として、 パーミッションチェックの間にワーキングメモリに挿入された Role オブジェクトはすべて、 認証済みユーザーが実際にそのロールのメンバーでない限り、 次回のパーミッションチェックが起こる前に削除されます。 ワーキングメモリには認証プロセスの結果として作成される java.security.Principal オブジェクトも含まれます。
RuleBasedPermissionResolver.instance().getSecurityContext().insert() を呼び出すと追加でワーキングメモリに長期に生存するファクトを挿入することができ、 これがオブジェクトをパラメータとして渡します。 Role オブジェクトは例外です。 各パーミッションチェックの開始時に同期されるためです。
c: が付けられています。 これは変数バインディングで、 条件に一致するオブジェクトを参照するために使用します (この例の場合は PermissionCheck)。 LHS の 2 行目には下の記述があります。
Role(name == "admin")
Role(name == "admin")
name を持つ Role オブジェクトがなければならないことを記述しています。 このため、 customer:delete パーミッションをチェックしていてユーザーが admin ロールのメンバーである場合にこのルールが実行されます。
c.grant()
c.grant()
c というオブジェクトの grant() メソッドを呼び出します。 これが PermissionCheck オブジェクトの変数バインディングです。 PermissionCheck オブジェクトの name プロパティと action プロパティの他に granted プロパティもあります。 これは最初は false に設定されています。 PermissionCheck の grant() を呼び出すと、granted プロパティは true に設定されます。 これはパーミッションのチェックが成功し、 ユーザーはパーミッションチェックを求めた操作を実行する権限を持っているということになります。
15.6.9.4. 非文字列のパーミッションターゲット リンクのコピーリンクがクリップボードにコピーされました!
MemberBlog インスタンスであり、 現在の認証済みユーザーが user ロールのメンバーであることが必要であると表現されています。
15.6.9.5. ワイルドカードによるパーミッションチェック リンクのコピーリンクがクリップボードにコピーされました!
PermissionCheck の action 制約を省略することでワイルドカードのパーミッションチェックの実装が可能になります (特定のパーミッション対象にすべての操作を許可します。
admin ロールを持つユーザーは、どの customer のパーミッションチェックに対しても すべての 操作が可能となります。
15.6.10. PersistentPermissionResolver リンクのコピーリンクがクリップボードにコピーされました!
PersistentPermissionResolver ではリレーショナルデータベースなどの永続的な保存場所からのパーミッションの読み込みを可能にします。 このパーミッションリゾルバでは ACL (Access Control List) スタイルのインスタンスベースのセキュリティを提供しており、 個別のユーザーやロールに対して特定のオブジェクトのパーミッションを割り当てることができます。 また、 同じようにして任意に名前が付けられた永続的なパーミッションの対象を割り当てることもできます (必ずしもオブジェクトまたはクラスベースである必要はありません)。
15.6.10.1. 設定 リンクのコピーリンクがクリップボードにコピーされました!
PersistentPermissionResolver を使用するには、 components.xml で有効な PermissionStore を設定する必要があります。 これが設定されていないと、 PersistentPermissionResolver はデフォルトのパーミッションストア 「JpaIdentityStore イベント」 を使用しようとします。 デフォルト以外のパーミッションストアを使用するには permission-store プロパティを以下のように設定します。
<security:persistent-permission-resolver
permission-store="#{myCustomPermissionStore}"/>
<security:persistent-permission-resolver
permission-store="#{myCustomPermissionStore}"/>
15.6.10.2. パーミッションストア リンクのコピーリンクがクリップボードにコピーされました!
PersistentPermissionResolver はパーミッションの永続化が行われるバックエンドの保存場所に接続するパーミッションストアを必要とします。 Seam は特に設定を必要としない PermissionStore 実装をひとつ JpaPermissionStore 提供しています。 これはリレーショナルデータベース内にパーミッションを保存します。 PermissionStore インターフェースを実装することで独自のパーミッションストアを作成することができます。 これは次のメソッドを定義します。
|
戻り値のタイプ
|
メソッド
|
詳細
|
|---|---|---|
List<Permission>
| listPermissions(Object target)
|
このメソッドは指定した対象のオブジェクトに付与されているすべての権限を表す
PermissionオブジェクトのListを返します。
|
List<Permission>
| listPermissions(Object target, String action)
|
このメソッドは指定した対象オブジェクトに付与された特定の操作を持つパーミッションをすべて表している
Permission オブジェクトの List を返します。
|
List<Permission>
| listPermissions(Set<Object> targets, String action)
|
このメソッドは指定した複数の対象オブジェクト一式に付与された特定の操作を持つパーミッションをすべて表している
Permission オブジェクトの List を返します。
|
boolean
| grantPermission(Permission)
|
このメソッドは指定された
Permission オブジェクトをバックエンドの保存場所に永続化し、成功すると true を返します。
|
boolean
| grantPermissions(List<Permission> permissions)
|
このメソッドは指定した
List 内に含まれる複数の Permission オブジェクトをすべて永続化し、 成功すると true を返します。
|
boolean
| revokePermission(Permission permission)
|
このメソッドは指定された
Permission オブジェクトを永続ストレージから削除します。
|
boolean
| revokePermissions(List<Permission> permissions)
|
このメソッドは指定されたリストにあるすべての
Permission オブジェクトを永続ストレージから削除します。
|
List<String>
| listAvailableActions(Object target)
|
このメソッドは指定した対象オブジェクトのクラスに対して使用可能な全操作 (文字列型) の一覧を返すはずです。 パーミッション管理と併用して特定のクラスのパーミッションを付与するためのユーザーインターフェース構築に使用されます。
|
15.6.10.3. JpaPermissionStore リンクのコピーリンクがクリップボードにコピーされました!
PermissionStore 実装です。 パーミッションをリレーショナルデータベースに保存します。 使用する前に、 ユーザーとロールのパーミッションの保存用に 1 つまたは 2 つのエンティティクラスでの設定が必要です。 これらのエンティティクラスには特殊なセキュリティアノテーション一式を付与して、 格納されるパーミッションの各種の側面に対応するエンティティプロパティを設定しなければなりません。
user-permission-class プロパティのみです。 ユーザーパーミッションの保存場所とロールパーミッションの保存場所に別々のテーブルを使用する場合は user-permission-class プロパティも設定する必要があります。
<security:jpa-permission-store
user-permission-class="com.acme.model.AccountPermission"/>
<security:jpa-permission-store
user-permission-class="com.acme.model.AccountPermission"/>
<security:jpa-permission-store
user-permission-class="com.acme.model.UserPermission"
role-permission-class="com.acme.model.RolePermission"/>
<security:jpa-permission-store
user-permission-class="com.acme.model.UserPermission"
role-permission-class="com.acme.model.RolePermission"/>
15.6.10.3.1. パーミッションアノテーション リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.annotations.security.permission パッケージにある特別なアノテーション一式で設定を行う必要があります。 次の表でこれらのアノテーションを説明します。
|
アノテーション
|
ターゲット
|
詳細
|
|---|---|---|
@PermissionTarget
| FIELD,METHOD
|
このアノテーションはパーミッションの対象を含んでいるエンティティのプロパティを識別します。 プロパティは
java.lang.String タイプでなければなりません。
|
@PermissionAction
| FIELD,METHOD
|
このアノテーションはパーミッションの操作を含んでいるエンティティプロパティを識別します。 このプロパティは
java.lang.String タイプでなければなりません。
|
@PermissionUser
| FIELD,METHOD
|
このアノテーションはパーミッションの受信者のユーザーを含んでいるエンティティプロパティを識別します。 このプロパティは
java.lang.String タイプで、ユーザーのユーザー名を含んでいなければなりません。
|
@PermissionRole
| FIELD,METHOD
|
このアノテーションはパーミッションの受信者のロールを含んでいるエンティティプロパティを識別します。 このプロパティは
java.lang.String タイプで、ロール名を含んでいなければなりません。
|
@PermissionDiscriminator
| FIELD,METHOD
|
このアノテーションはユーザーパーミッションとロールパーミッションの両方を同じエンティティまたはテーブルに保存する場合に使用します。 ユーザーパーミッションとロールパーミッションの区別に使用するエンティティのプロパティを識別します。 デフォルトでは、 列値が文字列リテラルの
user を含む場合はその記録はユーザーパーミッションとして処理されます。 文字列リテラルの role を含む場合はロールパーミッションとして処理されます。 また、 アノテーション中で userValue と roleValue のプロパティを指定するとこれらのデフォルトを無効にすることもできます。 例えば、 user の代わりに u を、role の代わりに r を使うには、 以下のようにアノテーションを記述します。
@PermissionDiscriminator( userValue = "u", roleValue = "r")
|
15.6.10.3.2. エンティティの例 リンクのコピーリンクがクリップボードにコピーされました!
getDiscriminator() メソッドに @PermissionDiscriminator アノテーションを付与して、 JpaPermissionStore にユーザーのパーミッションを表す記録とロールのパーミッションを表す記録を判定させています。 getRecipient() メソッドには @PermissionUser と @PermissionRole の両アノテーションが付与されています。 discriminator プロパティの値に応じて、 エンティティの recipient プロパティはユーザーの名前かロールの名前のいずれかを含むということになります。
15.6.10.3.3. クラス固有のパーミッションの設定 リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.annotation.security.permission パッケージに含まれるパーミッションは、対象クラスに対して許可可能な固有のパーミッション一式を設定するのに使用することができます。
|
アノテーション
|
ターゲット
|
詳細
|
|---|---|---|
@Permissions
| TYPE
|
コンテナのアノテーションです。
@Permission アノテーションの配列を含むことができます。
|
@Permission
| TYPE
|
このアノテーションでは対象クラスに対して許可可能なパーミッション操作を 1 つ定義します。 その
action プロパティを指定する必要があり、ビットマスク値でパーミッションの操作を永続化する場合にはオプションの mask プロパティも指定する必要があります (次項を参照)。
|
view と comment の 2 つのパーミッションアクションを MemberImage エンティティクラスに対して宣言する方法を示しています。
15.6.10.3.4. パーミッションマスク リンクのコピーリンクがクリップボードにコピーされました!
action プロパティまたは列と共に永続化されます。 ビットマスク化した整数値を使ってパーミッションの操作一覧を保存することができます。 これにより大量のパーミッションの永続化に必要となる物理的な保存場所を低減します。
MemberImage (エンティティ Bean) インスタンスの view と comment の両方のパーミッションが付与された場合、 デフォルトではパーミッションエンティティの action プロパティは付与された 2 つのパーミッションアクションを表す「view,comment」を含みます。 または、 以下のように定義したビットマスク値を使用している場合は
action プロパティには「3」が含まれます (bit 1 と 2 が on の状態)。 特定の対象クラスに対して許可可能な操作が大量にある場合には、 アクションにビットマスクを使用することにより、 パーミッションの記録に必要な保存領域が大幅に低減します。
重要
mask の指定値は 2 の n 乗になっていなければなりません。
15.6.10.3.5. 識別子ポリシー リンクのコピーリンクがクリップボードにコピーされました!
JpaPermissionStore は特定のオブジェクトのインスタンスを固有に識別できなければなりません。 これを行うには各対象クラスに 識別子ストラテジー を割り当てることにより一意の識別子の値を生成することができます。 各識別子のストラテジー実装は特定のクラスタイプの一意識別子の生成方法を認識するので、 新しい識別子ストラテジーはシンプルです。
IdentifierStrategy インターフェースは非常に単純で、2 つのメソッドを宣言しているだけです。
public interface IdentifierStrategy {
boolean canIdentify(Class targetClass);
String getIdentifier(Object target);
}
public interface IdentifierStrategy {
boolean canIdentify(Class targetClass);
String getIdentifier(Object target);
}
canIdentify() は true を返します。第 2 のメソッド getIdentifier() は指定された対象オブジェクトに対して一意の識別子の値を返します。
IdentifierStrategy 実装、 ClassIdentifierStrategy、 EntityIdentifierStrategy も提供しています。 これについては次項で説明します。
org.jboss.seam.annotations.security.permission.Identifier アノテーションを付与し、 IdentifierStrategy インターフェースの具体的な実装に値を設定します。 name プロパティを指定することもできます (効果は使用される IdentifierStrategy 実装により異なります)。
15.6.10.3.6. ClassIdentifierStrategy リンクのコピーリンクがクリップボードにコピーされました!
@Identifier アノテーション中の name の値を使用します。 name プロパティを与えないと識別子ストラテジーはクラスのコンポーネント名を使用しようとします (クラスが Seam コンポーネントの場合)。 最後の手段としてクラス名に基づいた識別子を作成します (パッケージ名を除く)。 たとえば、 以下の例にあるクラスの識別子は customer となります。
@Identifier(name = "customer")
public class Customer {...}
@Identifier(name = "customer")
public class Customer {...}
customerAction となります。
@Name("customerAction")
public class CustomerAction {...}
@Name("customerAction")
public class CustomerAction {...}
Customer となります。
public class Customer {...}
public class Customer {...}
15.6.10.3.7. EntityIdentifierStrategy リンクのコピーリンクがクリップボードにコピーされました!
ClassIdentifierStrategy のルールと同様です。主キーの値 (エンティティの ID) は PersistenceProvider コンポーネントを使って取得でき、 Seam アプリケーションでどの永続性実装を使用しているかに関わらず値を決定できます。 @Entity でアノテートされていないエンティティについては、 エンティティクラス自身に下のように明示的にアイデンティティストラテジーを設定する必要があります。
@Identifier(value = EntityIdentifierStrategy.class)
public class Customer {...}
@Identifier(value = EntityIdentifierStrategy.class)
public class Customer {...}
id が 1 の Customer のインスタンスに対する識別子は Customer:1 となります。 エンティティクラスに次のような明示的な識別子名のアノテーションがあれば
@Entity @Identifier(name = "cust")
public class Customer {...}
@Entity @Identifier(name = "cust")
public class Customer {...}
id が 123 の Customer は 「cust:123」という識別子を持つことになります。
15.7. パーミッション管理 リンクのコピーリンクがクリップボードにコピーされました!
PermissionManager コンポーネント)。
15.7.1. PermissionManager リンクのコピーリンクがクリップボードにコピーされました!
PermissionManager コンポーネントはアプリケーションスコープの Seam コンポーネントであり、 数種類のパーミッション管理の方法を提供しています。 使用する前にパーミッションストアで設定する必要があります。 デフォルトでは JpaPermissionStore の使用を試行します。 カスタムのパーミッションストアを設定するためには、components.xml に permission-store プロパティを指定します。
<security:permission-manager permission-store="#{ldapPermissionStore}"/>
<security:permission-manager permission-store="#{ldapPermissionStore}"/>
PermissionManager 提供の各メソッドの詳細を示します。
|
戻り値のタイプ
|
メソッド
|
詳細
|
|---|---|---|
List<Permission>
| listPermissions(Object target, String action)
|
指定されたターゲットとアクションに対して付与されたすべてのパーミッションを示す
Permission オブジェクトの一覧を返します。
|
List<Permission>
| listPermissions(Object target)
|
指定されたターゲットとアクションに対して付与されたすべてのパーミッションを示す
Permission オブジェクトの一覧を返します。
|
boolean
| grantPermission(Permission permission)
|
バックエンドのパーミッションストアに指定した
Permission を永続化 (許可) します。 操作が成功すると true を返します。
|
boolean
| grantPermissions(List<Permission> permissions)
|
バックエンドのパーミッションストアに指定した複数の
Permission の 一覧を永続化 (許可) します。 操作が成功すると true を返します。
|
boolean
| revokePermission(Permission permission)
|
バックエンドのパーミッションストアから指定した
Permission を削除 (無効) にします。 操作が成功すると true を返します。
|
boolean
| revokePermissions(List<Permission> permissions)
|
バックエンドのパーミッションストアから指定した複数の
Permission の一覧を削除 (無効) にします。 操作が成功すると true を返します。
|
List<String>
| listAvailableActions(Object target)
|
指定された対象ターゲットに対する適用可能な操作の一覧を返します。 このメソッドが返す操作は、対象オブジェクトのクラスに設定されている
@Permission アノテーションにより異なります。
|
15.7.2. PermissionManager 操作のためのパーミッションチェック リンクのコピーリンクがクリップボードにコピーされました!
PermissionManager メソッドを起動するためには、現在の認証ユーザーがその管理操作を実行するために承認されなければなりません。 下の表に特定のメソッド呼び出しに必要なパーミッションを記載します。
|
メソッド
|
パーミッションターゲット
|
パーミッションのアクション
|
|---|---|---|
listPermissions()
|
指定された
target
| seam.read-permissions
|
grantPermission()
|
指定された
Permission の対象、 または指定した複数の Permission の一覧に対する各対象 (呼び出すメソッドにより異なる)
| seam.grant-permission
|
grantPermission()
|
指定された
Permission の対象
| seam.grant-permission
|
grantPermissions()
|
指定された
Permission の一覧の各対象
| seam.grant-permission
|
revokePermission()
|
指定された
Permission の対象
| seam.revoke-permission
|
revokePermissions()
|
指定された
Permission の一覧の各対象
| seam.revoke-permission
|
15.8. SSL によるセキュリティ リンクのコピーリンクがクリップボードにコピーされました!
pages.xml でページの scheme を指定します。以下の例では HTTPS を使った /login.xhtml ビューの設定方法について示しています。
<page view-id="/login.xhtml" scheme="https"/>
<page view-id="/login.xhtml" scheme="https"/>
s:link や s:button の JSF コントロールを拡張しリンクを正しいプロトコルで表示します (view を指定した場合)。 前述の例を基にして、 /login.xhtml は HTTPS を使用するよう設定されているため以下のリンクは HTTPS を使用します。
<s:link view="/login.xhtml" value="Login"/>
<s:link view="/login.xhtml" value="Login"/>
scheme="https" ページを HTTP で閲覧しようとすると HTTPS を使用する同じページへのリダイレクトが引き起こされます。
scheme として定義するには、次の行を pages.xml に追加してください。
<page view-id="*" scheme="http" />
<page view-id="*" scheme="http" />
components.xml に次の行を追加します。
<web:session invalidate-on-scheme-change="true"/>
<web:session invalidate-on-scheme-change="true"/>
15.8.1. デフォルトのポートの上書き リンクのコピーリンクがクリップボードにコピーされました!
pages エレメントの http-port 属性と https-port属性を指定することで pages.xml 内で設定することができます。
15.9. CAPTCHA リンクのコピーリンクがクリップボードにコピーされました!
15.9.1. CAPTCHA サーブレットの設定 リンクのコピーリンクがクリップボードにコピーされました!
web.xml に追加します。
15.9.2. フォームへの CAPTCHA の追加 リンクのコピーリンクがクリップボードにコピーされました!
graphicImage コントロールが CAPTCHA チャレンジを表示し、 inputText がユーザーからのレスポンスを受けます。 このレスポンスはフォームが送信された時に自動的に CAPTCHA と検証されます。
15.9.3. CAPTCHA アルゴリズムのカスタマイズ リンクのコピーリンクがクリップボードにコピーされました!
15.10. セキュリティイベント リンクのコピーリンクがクリップボードにコピーされました!
|
イベントキー
|
詳細
|
|---|---|
org.jboss.seam.security.loginSuccessful
|
ログイン試行に成功すると引き起こされます。
|
org.jboss.seam.security.loginFailed
|
ログイン試行に失敗すると引き起こされます。
|
org.jboss.seam.security.alreadyLoggedIn
|
すでに認証されているユーザーが再度ログインを試行した場合に引き起こされます。
|
org.jboss.seam.security.notLoggedIn
|
ユーザーがログインしていない場合にセキュリティチェックが失敗すると引き起こされます。
|
org.jboss.seam.security.notAuthorized
|
ログインしているがユーザーに十分な権限がないためセキュリティチェックに失敗した場合に引き起こされます。
|
org.jboss.seam.security.preAuthenticate
|
ユーザー認証の直前に引き起こされます。
|
org.jboss.seam.security.postAuthenticate
|
ユーザー認証の直後に引き起こされます。
|
org.jboss.seam.security.loggedOut
|
ユーザーがログアウトした後に引き起こされます。
|
org.jboss.seam.security.credentialsUpdated
|
ユーザーの資格情報が変更されている場合に引き起こされます。
|
org.jboss.seam.security.rememberMe
|
Identity の rememberMe プロパティが変更されると引き起こされます。
|
15.11. 別の権限での実行 リンクのコピーリンクがクリップボードにコピーされました!
RunAsOperation クラスで対応します。 このクラスは、単一の一組の操作に対して Principal か Subject のいずれか、またはユーザーのロールを無効にすることができます。
RunAsOperation の使い方を示します。addRole() メソッドを呼び出し、操作の間に「借りる」ロールセットを提供します。execute() メソッドは上位特権で実行されるコードを持っています。
getPrincipal() や getSubject() メソッドを無効にしてその操作の間だけ Principal インスタンスや Subject インスタンスを使用するよう指定することができます。 最後に、 RunAsOperation を実行するために run() メソッドを使用します。
15.12. Identity コンポーネントの拡張 リンクのコピーリンクがクリップボードにコピーされました!
companyCode フィールドで拡張した Identity コンポーネントによって資格証明が処理される例を示します (通常は Credentials コンポーネントで処理されます)。 APPLICATION の install precedence により、組み込みの Identity に代わりこの拡張された Identity が必ずインストールされるようにします。
警告
Identity コンポーネントは @Startup の印を付けてください。 これにより SESSION コンテキストが開始された直後に使用できるようになります。これをしないと、特定の Seam 機能が使用するアプリケーションで動作しないことがあります。
15.13. OpenID リンクのコピーリンクがクリップボードにコピーされました!
警告
http://maximoburrito.myopenid.com などの URL 形式をとります (識別子の http:// の部分はサイトにログインするときは省略して構いません)。 Web アプリケーション (relying party (証明書利用者) として知られる) は接続する OpenID サーバーを決定し、認証用のリモートサイトにリダイレクトします。認証に成功するとそのユーザーには本人のアイデンティティを証明する (暗号化されて安全な) トークンが与えられ、元の Web アプリケーションに戻されます。 これでローカルの Web アプリケーションはアプリケーションにアクセスしているユーザーが提示された OpenID を所有していると仮定できます。
15.13.1. OpenID の設定 リンクのコピーリンクがクリップボードにコピーされました!
opemid4java パッケージを使用し、 Seam 統合を利用するため 4 種類の JAR が追加で必要です。 htmlparser.jar、 openid4java.jar、 openxri-client.jar、 openxri-syntax.jar です。
OpenIdPhaseListener を必要とし、 faces-config.xml ファイルに追加する必要があります。 フェーズリスナーは OpenID プロバイダからのコールバックを処理してローカルアプリケーションへの再エントリを許可します。
org.jboss.seam.security.openid.openid は、openid4java クラス群がクラスパスにある場合には自動的にインストールされます。
15.13.2. OpenIDLgin フォームの提示 リンクのコピーリンクがクリップボードにコピーされました!
#{openid.id} の値がユーザーの OpenID を受け取り、 #{openid.login} アクションが認証要求を開始します。
<h:form>
<h:inputText value="#{openid.id}" />
<h:commandButton action="#{openid.login}" value="OpenID Login"/>
</h:form>
<h:form>
<h:inputText value="#{openid.id}" />
<h:commandButton action="#{openid.login}" value="OpenID Login"/>
</h:form>
OpenIdPhaseListener によって提供される Seam の疑似ビュー /openid.xhtml を介してアプリケーションに戻されます。 アプリケーションは、 ユーザーがそのアプリケーションから全く離れなかったかのようにそのビューから pages.xml の操作で OpenID のレスポンスを処理できます。
15.13.3. 即時ログイン リンクのコピーリンクがクリップボードにコピーされました!
#{openid.loginImmediately()} アクションを使ってこれを処理する方法を示します。
loginImmediately() アクションは OpenID が有効であるかどうかを確認します。 有効であればアイデンティティコンポーネントに OpenIdPrincipal が追加され、ユーザーがログインしたと印を付けます (#{identity.loggedIn} に true の印を付ける)。そして loginImmediately() アクションが true を返します。OpenID が有効ではない場合、 メソッドは false を返してそのユーザーはアプリケーションに未認証で入ります。 ユーザーの OpenID が有効の場合、 #{openid.validatedId} の式を使ってアクセス可能となるため #{openid.valid} は true になります。
15.13.4. ログインの保留 リンクのコピーリンクがクリップボードにコピーされました!
#{openid.valid} プロパティを確認して、ユーザーをローカルの登録または処理ページにリダイレクトしなければなりません。 そこでさらに情報を求めてからローカルのユーザーアカウントを作成する、 または CAPTCHA を提示してプログラム的な登録を回避することができます。 プロセスが完了したら、org.jboss.seam.security.openid.OpenId コンポーネントとの直接連携または EL (前述を参照) のいずれかを介して loginImmediately メソッドを呼び出すことでユーザーをログインさせることができます。 また、 カスタムのコードを記述して Seam のアイデンティティコンポーネントと連携させることによりカスタマイズな操作を作成することもできます。
15.13.5. ログアウト リンクのコピーリンクがクリップボードにコピーされました!
#{openid.logout} を呼び出すことで実行します。 このメソッドは Seam Security を使用していない場合は直接呼び出すことができます。Seam Security を使用している場合は継続して #{identity.logout} を使用し、イベントハンドラをインストールしてログアウトイベントをキャプチャし、 OpenID ログアウトメソッドを呼び出します。
<event type="org.jboss.seam.security.loggedOut">
<action execute="#{openid.logout}" />
</event>
<event type="org.jboss.seam.security.loggedOut">
<action execute="#{openid.logout}" />
</event>
第16章 国際化とローカリゼーションおよびテーマ リンクのコピーリンクがクリップボードにコピーされました!
注記
16.1. アプリケーションの国際化 リンクのコピーリンクがクリップボードにコピーされました!
16.1.1. アプリケーションサーバーの設定 リンクのコピーリンクがクリップボードにコピーされました!
URIEncoding="UTF-8" 属性を $JBOSS_HOME/server/$PROFILE/deploy/jboss-web.deployer/server.xml のコネクタ設定に追加します。
<Connector port="8080" URIEncoding="UTF-8"/>
<Connector port="8080" URIEncoding="UTF-8"/>
<Connector port="8080" useBodyEncodingForURI="true"/>
<Connector port="8080" useBodyEncodingForURI="true"/>
16.1.2. 翻訳されたアプリケーション文字列 リンクのコピーリンクがクリップボードにコピーされました!
\uXXXX を使用するといずれの Java ファイルでも Unicode 文字を表すことができます。 XXXX はその文字を表す 16 進数です。
native2ascii ツールを使って、Unicode エスケープシーケンスで ASCII 以外の文字を表すものに変換することができます。
native2ascii -encoding UTF-8 messages_cs.properties > messages_cs_escaped.properties
$ native2ascii -encoding UTF-8 messages_cs.properties > messages_cs_escaped.properties
16.1.3. その他のエンコーディング設定 リンクのコピーリンクがクリップボードにコピーされました!
<f:view locale="cs_CZ"/> タグを使用します (この locale 値は JSF にチェコ語を使用するよう指示します)。XML にローカライズされた文字列を埋め込む場合に、XML ドキュメント自体のエンコーディングを変更したいと思われるかもしれません。これを行うには XML 宣言の <?xml version="1.0" encoding="UTF-8"?> にある encoding 属性値を変更します。
components.xml で設定します。
<web:character-encoding-filter encoding="UTF-8" override-client="true"
url-pattern="*.seam" />
<web:character-encoding-filter encoding="UTF-8" override-client="true"
url-pattern="*.seam" />
16.2. ロケール リンクのコピーリンクがクリップボードにコピーされました!
java.util.Locale の関連付けられたインスタンスを持ち、 アプリケーションに対しては locale という名前のコンポーネントとして使用可能です。 通常の環境では、 ロケールに特別な設定は不要です。 Seam ではアクティブなロケールの決定は次のように JSF に委譲します。
- ロケールが HTTP 要求と関連付けられ (ブラウザのロケール)、 そのロケールが
faces-config.xmlにあるサポートロケールの一覧にある場合は、 そのロケールをその後のセッションに使用します。 - これ以外で、 デフォルトロケールが
faces-config.xml中に指定されていた場合、 そのロケールをその後のセッションに使用します。 - いずれにも該当しない場合、 サーバのデフォルトロケールを使用します。
org.jboss.seam.international.localeSelector.language、 org.jboss.seam.international.localeSelector.country、 org.jboss.seam.international.localeSelector.variant により手作業でのロケール設定が 可能 ですが、以前に示した方法ではなくてこれを実行する妥当な理由は考え付きません。
faces-config.xml のサポートロケールの全一覧が必要な場合は次を使います。
org.jboss.seam.international.localeConfig コンポーネントを使ってサーバーのデフォルトロケールとサポートされているロケールを設定することができます。 まず、 Seam コンポーネント記述子で Seam 国際パッケージの XML 名前空間を宣言します。 次にデフォルトのロケールとサポートされるロケールを次のように定義します。
<international:locale-config default-locale="fr_CA"
supported-locales="en fr_CA fr_FR"/>
<international:locale-config default-locale="fr_CA"
supported-locales="en fr_CA fr_FR"/>
16.3. ラベル リンクのコピーリンクがクリップボードにコピーされました!
<f:loadBundle /> により JSF はユーザーインターフェースのラベルや説明用テキストの国際化に対応しています。 Seam アプリケーションではこの方法をとるか、 組み込みの EL 式を利用したテンプレート化ラベルの表示に Seam の messages コンポーネントを利用することができます。
16.3.1. ラベルの定義 リンクのコピーリンクがクリップボードにコピーされました!
java.util.ResourceBundle で利用できる国際化ラベルを org.jboss.seam.core.resourceBundle としてアプリケーションに対して使用できるようにします。 デフォルトでは、 Seam で使用されるリソースバンドルは messages の名称なので messages.properties、 messages_en.properties、 messages_en_AU.properties などの名称のファイルにラベルを定義する必要があります。 これらのファイルは通常 WEB-INF/classes ディレクトリに属します。
messages_en.properties では次のようになります。
Hello=Hello
Hello=Hello
messages_en_AU.properties では次のようになります。
Hello=G'day
Hello=G'day
org.jboss.seam.core.resourceLoader.bundleNames と呼ばれる Seam 設定プロパティを設定することで、リソースバンドルに別の名前を選択することができます。 リソースバンドル名の一覧を指定してメッセージの検索をさせる (深さ優先) こともできます。
/ と最後の拡張子を除去します。 つまり /welcome/hello.jsp にのみメッセージを表示したいのであれば、 表示させるメッセージを welcome/hello_en.properties に配置します。
pages.xml に明示的なバンドル名を指定することもできます。
<page view-id="/welcome/hello.jsp" bundle="HelloMessages"/>
<page view-id="/welcome/hello.jsp" bundle="HelloMessages"/>
HelloMessages.properties に定義されたメッセージを /welcome/hello.jsp で使うことができます。
16.3.2. ラベルの表示 リンクのコピーリンクがクリップボードにコピーされました!
<f:loadBundle ... /> を入力しなくてもラベルを使用することができます。 代わりに以下のように入力します。
<h:outputText value="#{messages['Hello']}"/>
<h:outputText value="#{messages['Hello']}"/>
<h:outputText value="#{messages.Hello}"/>
<h:outputText value="#{messages.Hello}"/>
Hello=Hello, #{user.firstName} #{user.lastName}
Hello=Hello, #{user.firstName} #{user.lastName}
Hello=G'day, #{user.firstName}
Hello=G'day, #{user.firstName}
@In private Map<String, String> messages;
@In private Map<String, String> messages;
@In("#{messages['Hello']}") private String helloMessage;
@In("#{messages['Hello']}") private String helloMessage;
16.3.3. Faces メッセージ リンクのコピーリンクがクリップボードにコピーされました!
facesMessages コンポーネントはユーザーに成功か失敗かを表示するのに便利な方法です。 上述した機能は Faces のメッセージにも有効です。
Hello, Gavin King あるいは G'day, Gavin と表示されます。
16.4. タイムゾーン リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.international.timezone という名称の java.util.Timezone のセッションスコープのインスタンスと、org.jboss.seam.international.timezoneSelector という名称のタイムゾーンを変更する Seam コンポーネントもあります。 デフォルトでは、タイムゾーンはサーバーのデフォルトタイムゾーンです。 タイムゾーンが <f:convertDateTime> を使用して明示的に指定されない限り、 残念ながら JSF 仕様ではすべての日付と時刻は UTC を前提としており、 UTC として表示されます。
<s:convertDateTime> タグを備えています。
16.5. テーマ リンクのコピーリンクがクリップボードにコピーされました!
default テーマは default.properties に一連のエントリとして定義されます。 例えば、default.properties は以下のように定義します。
css ../screen.css template /template.xhtml
css ../screen.css template /template.xhtml
<link href="#{theme.css}" rel="stylesheet" type="text/css" />
<link href="#{theme.css}" rel="stylesheet" type="text/css" />
<link href="#{facesContext.externalContext.requestContextPath}#{theme.css}"
rel="stylesheet" type="text/css" />
<link href="#{facesContext.externalContext.requestContextPath}#{theme.css}"
rel="stylesheet" type="text/css" />
<ui:composition> で使用されるテンプレートを適用できます。
<h:selectOneMenu value="#{themeSelector.theme}">
<f:selectItems value="#{themeSelector.themes}"/>
</h:selectOneMenu>
<h:commandButton action="#{themeSelector.select}" value="Select Theme"/>
<h:selectOneMenu value="#{themeSelector.theme}">
<f:selectItems value="#{themeSelector.themes}"/>
</h:selectOneMenu>
<h:commandButton action="#{themeSelector.select}" value="Select Theme"/>
16.6. クッキーによるロケールとテーマ設定の永続化 リンクのコピーリンクがクリップボードにコピーされました!
components.xml で cookie-enabled プロパティを設定します。
第17章 Seam Text リンクのコピーリンクがクリップボードにコピーされました!
<s:formattedText/> コントロールが備わっています。 Seam Text は ANTLR ベースのパーサを利用して実装します (ANTLR に関する知識は必要ありません)。
17.1. フォーマットの基本 リンクのコピーリンクがクリップボードにコピーされました!
It's easy to make *emphasized*, |monospaced|, ~deleted~, super^scripted^ or _underlined_ text.
<s:formattedText/> を使って表示すると、 以下の HTML が生成されます。
<p> It's easy to make <i>emphasized</i>, <tt>monospaced</tt>, <del>deleted</del>, super<sup>scripted</sup> or <u>underlined</u> text. </p>
<p>
It's easy to make <i>emphasized</i>, <tt>monospaced</tt>,
<del>deleted</del>, super<sup>scripted</sup> or
<u>underlined</u> text.
</p>
+ は見出しに使用します。
# 文字は順序指定された一覧のアイテムを作成します。順序指定されていない一覧は = 文字を使います。
17.2. 特殊な文字でのコードとテキストの記述 リンクのコピーリンクがクリップボードにコピーされました!
*、| # などの特殊文字や <, > and & などの HTML 文字は \ でエスケープすることができます。
You can write down equations like 2\*3\=6 and HTML tags like \<body\> using the escape character: \\.
You can write down equations like 2\*3\=6 and HTML tags like \<body\> using the escape character: \\.
<p> You can write down equations like 2*3=6 and HTML tags like <body> using the escape character: \. </p>
<p>
You can write down equations like 2*3=6 and HTML tags
like <body> using the escape character: \.
</p>
This is a |<tag attribute="value"/>| example.
This is a |<tag attribute="value"/>| example.
17.3. リンク リンクのコピーリンクがクリップボードにコピーされました!
Go to the Seam website at [=>http://jboss.com/products/seam].
Go to the Seam website at [=>http://jboss.com/products/seam].
Go to [the Seam website=>http://jboss.com/products/seam].
Go to [the Seam website=>http://jboss.com/products/seam].
17.4. HTML の記述 リンクのコピーリンクがクリップボードにコピーされました!
You might want to link to
<a href="http://jboss.com/products/seam">something cool</a>,
or even include an image: <img src="/logo.jpg"/>
You might want to link to
<a href="http://jboss.com/products/seam">something cool</a>,
or even include an image: <img src="/logo.jpg"/>
<table> <tr><td>First name:</td><td>Gavin</td></tr> <tr><td>Last name:</td><td>King</td></tr> </table>
<table>
<tr><td>First name:</td><td>Gavin</td></tr>
<tr><td>Last name:</td><td>King</td></tr>
</table>
17.5. SeamTextParser の使用 リンクのコピーリンクがクリップボードにコピーされました!
<s:formattedText/> JSF コンポーネントは内部的に org.jboss.seam.text.SeamTextParser を使用します。 このクラスを直接使って独自のテキスト解析機能、 レンダリング機能、 HTML サニテーションの手順を実装することができます。 JavaScript ベースの HTML エディタなどリッチテキストの入力用にカスタムのフロントエンドインターフェースがある場合、 クロスサイトスクリプティング (XSS) 攻撃から防御する目的でユーザーの入力を確認する場合に便利です。 またカスタムの Wiki テキスト解析やレンダリングエンジンとしても使用できます。
linkTag() と paragraphOpenTag() メソッドは、レンダリングされた出力をカスタマイズするために無効にすることができる 2 種類のメソッドです。 これらのメソッドは通常、 String 出力を返します。 詳細については Java ドキュメントを参照してください。 org.jboss.seam.text.SeamTextParser.DefaultSanitizer Java ドキュメントには HTML のエレメント、 属性、 デフォルトでフィルタされる属性値などの詳細も記載されています。
第18章 iText PDF 生成 リンクのコピーリンクがクリップボードにコピーされました!
18.1. PDF サポートの使用 リンクのコピーリンクがクリップボードにコピーされました!
jboss-seam-pdf.jar により提供されます。 この JAR には iText JSF コントロール (PDF にレンダリング可能なビューを構成) と DocumentStore コンポーネント (ユーザーにレンダリングしたドキュメントを提供) が含まれます。 アプリケーションに PDF サポートを含ませるには jboss-seam-pdf.jar を WEB-INF/lib ディレクトリに iText の JAR ファイルと共に含ませます。 Seam の iText サポートを使用する上で必要な設定はこれだけです。
seam-ui パッケージの使用も必要となります。
examples/itext プロジェクトには実行可能なデモ用 PDF サポートのサンプルが含まれています。 正確なパッケージ化の導入を行い、 現在サポートされている PDF 生成の主要な機能を実際に示すサンプルがいくつか含まれています。
18.1.1. ドキュメントの作成 リンクのコピーリンクがクリップボードにコピーされました!
<p:document>
|
説明
ドキュメントは
http://jboss.com/products/seam/pdf 名前空間にあるタグを使い Facelet XHTML ファイルで生成されます。ドキュメントにはそのルートに必ず document タグがあるはずです。document タグは Seam が ドキュメントを DocumentStore に生成し、その格納コンテンツに HTML リダイレクトをレンダリングするよう準備を行います。
Attributes
メタデータ属性
使用方法
<p:document xmlns:p="http://jboss.com/products/seam/pdf"> The document goes here. </p:document>
|
18.1.2. 基本的なテキストのエレメント リンクのコピーリンクがクリップボードにコピーされました!
<p:image> タグと <p:paragraph> タグはシンプルなドキュメントの基盤を形成します。 <p:font> のようなタグはスタイル情報を提供します。
<p:paragraph>
|
説明
ほとんどの場合、 テキストを段落ごとに区切ることでテキストの断片に論理的な流れやフォーマットおよびスタイルを与えることができるようになります。
Attributes
使用方法
<p:paragraph alignment="justify"> This is a simple document. It isn't very fancy. </p:paragraph>
|
<p:text>
|
説明
text タグにより通常の JSF 変換メカニズムを使用して、アプリケーションデータからテキストの断片を生成することができます。HTML ドキュメントをレンダリングする場合に使用する outputText タグと非常に似ています。
Attributes
使用方法
|
<p:html>
|
説明
html タグは HTML コンテンツを PDF にレンダリングします。
Attributes
使用方法
|
<p:font>
|
説明
font タグはその中のすべてのテキストに使用されるデフォルトフォントを定義します。
Attributes
使用方法
<p:font name="courier" style="bold" size="24"> <p:paragraph>My Title</p:paragraph> </p:font>
|
<p:textcolumn>
|
説明
p:textcolumn はテキストの流れを制御するために使用可能なテキスト列を挿入します。最も一般的な使用方法は、右から左の方向のフォントに対応することです。
Attributes
使用方法
<p:textcolumn left="400" right="600" direction="rtl">
<p:font name="/Library/Fonts/Arial Unicode.ttf"
encoding="Identity-H"
embedded="true">#{phrases.arabic}</p:font>
</p:textcolumn>
|
<p:newPage>
|
説明
p:newPage は改ページを挿入します。
使用方法
<p:newPage />
|
<p:image>
|
説明
p:image は画像をドキュメントに挿入します。画像はクラスパスまたは Web アプリケーションコンテキストから value 属性を使ってロードすることができます。
リソースはアプリケーションコードで動的に生成することもできます。
imageData 属性は値バインディング式を指定することができ、 この値は java.awt.Image オブジェクトです。
Attributes
使用方法
<p:image value="/jboss.jpg" />
<p:image value="#{images.chart}" />
|
<p:anchor>
|
説明
p:anchor はドキュメントからクリックできるリンクを定義します。次の属性に対応します。
Attributes
使用方法
|
18.1.3. ヘッダーとフッター リンクのコピーリンクがクリップボードにコピーされました!
<p:header>
<p:footer>
|
説明
p:header と p:footer のコンポーネントにより、生成されたドキュメントの各ページにヘッダーとフッターを配置します。ヘッダーとフッターの宣言はドキュメントの冒頭に出現するはずです。
Attributes
使用方法
|
<p:pageNumber>
|
説明
現在のページ番号は
p:pageNumber タグを使うとヘッダーまたはフッターの内側に配置できます。このページ番号タグはヘッダーまたはフッターのコンテキスト内でのみ、1 度だけ使用可能です。
使用方法
<p:footer borderWidthTop="1" borderColorTop="blue" borderWidthBottom="0" alignment="center"> Why Seam? [<p:pageNumber />] </p:footer>
|
18.1.4. 章とセクション リンクのコピーリンクがクリップボードにコピーされました!
<p:chapter>
<p:section>
|
説明
生成されるドキュメントが book または article の構造をとる場合、
p:chapter と p:section のタグを使用して構成することができます。セクションは章の内側でのみ使用できますが、必要に応じていずれの深さにもネストさせることができます。ほとんどの PDF ビューアはドキュメント内の章とセクション間を簡単に移動できる機能を備えています。
Attributes
使用方法
|
<p:header>
|
説明
いずれの章やセクションにも
p:title を含むことができます。タイトルは章やセクション番号の隣に表示されます。タイトルの本文には raw テキストを含めるか、p:paragraph とすることも可能です。
|
18.1.5. 一覧 リンクのコピーリンクがクリップボードにコピーされました!
p:list と p:listItem のタグを使って表示させることができます。 一覧には適宜ネストされたサブリストを含ませることもできます。 一覧のアイテムは一覧の外側では使用できません。 次のドキュメントは ui:repeat タグを使って Seam コンポーネントから取得した値の一覧を表示しています。
<p:list>
|
Attributes
使用方法
|
<p:listItem>
|
説明
p:listItem は次の属性に対応しています。
Attributes
使用方法
...
|
18.1.6. 表 リンクのコピーリンクがクリップボードにコピーされました!
p:table と p:cell のタグを使って作成することができます。 多くの表構成とは異なり、明示的な行の宣言はありません。 表に列が 3 つある場合は、3 セルで自動的に行を 1 つ形成します。 ヘッダーとフッターの行を宣言することができ、 表の構成が複数ページに渡る場合にはヘッダーとフッターは繰り返し使用されます。
<p:table>
|
説明
p:table は次の属性に対応しています。
Attributes
使用方法
|
<p:cell>
|
説明
p:cell は次の属性に対応しています。
Attributes
使用方法
<p:cell>...</p:cell>
|
18.1.7. ドキュメントの定数 リンクのコピーリンクがクリップボードにコピーされました!
18.1.7.1. 色の値 リンクのコピーリンクがクリップボードにコピーされました!
white、 gray、 lightgray、 darkgray、 black、 red、 pink、 yellow、 green、 magenta、 cyan、 blue です。
18.1.7.2. 位置調整の値 リンクのコピーリンクがクリップボードにコピーされました!
left、 right、 center、 justify、 justifyall に対応します。 縦方向の値は top、 middle、 bottom、 baseline です。
18.2. グラフ リンクのコピーリンクがクリップボードにコピーされました!
jboss-seam-pdf.jar で提供されます。 グラフは PDF ドキュメント内で使用でき、またはグラフは HTML ページ内でイメージになります。 グラフ作成を行うには JFreeChart ライブラリ (jfreechart.jar と jcommon.jar) を WEB-INF/lib ディレクトリに追加する必要があります。 現在、 円グラフ、 棒グラフ、 折れ線グラフの 3 種類のグラフに対応しています。
<p:chart>
|
説明
Seam コンポーネントにより Java ですでに作成されているグラフを表示します。
Attributes
使用方法
<p:chart chart="#{mycomponent.chart}" width="500" height="500" />
|
<p:barchart>
|
説明
棒グラフを表示します。
Attributes
使用方法
|
<p:linechart>
|
説明
折れ線グラフを表示します。
Attributes
使用方法
|
<p:piechart>
|
説明
円グラフを表示します。
Attributes
使用方法
|
<p:series>
|
説明
カテゴリデータはシリーズに分割できます。 シリーズタグを使ってデータセットをシリーズで分類し、そのシリーズ全体にスタイリングを適用します。
Attributes
使用方法
|
<p:data>
|
説明
データタグはグラフ内で表示される各データポイントを表現します。
Attributes
使用方法
<p:data key="foo" value="20" sectionPaint="#111111" explodedPercent=".2" /> <p:data key="bar" value="30" sectionPaint="#333333" /> <p:data key="baz" value="40" sectionPaint="#555555" sectionOutlineStroke="my-dot-style" />
|
<p:color>
|
説明
色コンポーネントは、色埋めされた形を描く場合に参照できる色または階調を宣言します。
Attributes
使用方法
<p:color id="foo" color="#0ff00f"/> <p:color id="bar" color="#ff00ff" color2="#00ff00" point="50 50" point2="300 300"/>
|
<p:stroke>
|
説明
グラフ内に線を描くのに使用する線を表します。
Attributes
使用方法
<p:stroke id="dot2" width="2" cap="round" join="bevel" dash="2 3" />
|
18.3. バーコード リンクのコピーリンクがクリップボードにコピーされました!
<p:barCode>
|
説明
バーコードイメージを表示します。
Attributes
使用方法
<p:barCode type="code128" barHeight="80" textSize="20" code="(10)45566(17)040301" codeType="code128_ucc" altText="My BarCode" />
|
18.4. 入力フォーム リンクのコピーリンクがクリップボードにコピーされました!
<p:form>
|
説明
埋めるフォームのテンプレートを定義します。
Attributes
|
<p:field>
|
説明
フィールド名をその値につなげます。
Attributes
|
18.5. Swing/AWT コンポーネントをレンダリングする リンクのコピーリンクがクリップボードにコピーされました!
<p:swing>
|
説明
Swing コンポーネントを PDF ドキュメントにレンダリングします。
Attributes
使用方法
<p:swing width="310" height="120" component="#{aButton}" />
|
18.6. iText の設定 リンクのコピーリンクがクリップボードにコピーされました!
/seam-doc.seam から PDF ドキュメントを提供します。 たとえば、 多くのユーザーは /myDocument.pdf などのように実際の PDF 名と拡張子を含んでいる URL が表示されるのを好みます。完全な名前のファイルを提供するには、DocumentStoreServlet に各ドキュメントタイプのマッピングが含まれる必要があります。
*.pdf*.xls*.csv
<servlet-name> および <url-pattern> サブ要素とともに <servlet-mapping> 要素を追加します。
use-extensions オプションは、生成されるドキュメントタイプに正しいファイル名拡張子を付けて URL を生成するよう DocumentStore コンポーネントに指示します。
documentStore の error-page プロパティを編集することで、ドキュメントが存在しない場合にデフォルトのビューが表示されるよう指定します。
<document:document-store use-extensions="true"
error-page="/documentMissing.seam" />
<document:document-store use-extensions="true"
error-page="/documentMissing.seam" />
第19章 Microsoft® Excel® 表計算アプリケーション リンクのコピーリンクがクリップボードにコピーされました!
19.1. Microsoft Excel のサポート リンクのコピーリンクがクリップボードにコピーされました!
WEB-INF/lib ディレクトリに jboss-seam-excel.jar と jxl.jar を含ませる必要があります。 jboss-seam-excel.jar にはドキュメントのレンダリング用ビューの構成に使用する Microsoft Excel JSF のコントロールとレンダリングされたドキュメントをユーザーに提供する DocumentStore コンポーネントが含まれます。 また、 web.xml ファイルの DocumentStore サーブレットを設定する必要があります。 Microsoft Excel Seam モジュールは seam-ui パッケージを必要とし、 また Facelets がビューテクノロジーとして使用されていなければなりません。
examples/excel プロジェクトでは実際の Microsoft Excel サポートのサンプルをご覧頂けます。 これはそのサポートによる表示された機能や正しいデプロイメントパッケージングなどを示しています。
ExcelWorkbook インターフェースを実装してから次を components.xml に登録します。
xmlns:excel="http://jboss.com/products/seam/excel"
xmlns:excel="http://jboss.com/products/seam/excel"
myExcelExporter に UIWorkbook タイプを設定します。 デフォルトは jxl ですが、 csv タイプを使って CSV を使用することもできます。
web.xml またはブラウザのセキュリティ制限が厳しすぎていないか確認してください (http://www.nwnetworks.com/iezones.htm/ を参照)。
19.2. 簡単なワークブックの作成 リンクのコピーリンクがクリップボードにコピーされました!
<h:dataTable> と同様に使用され、 List、 Set、 Map、 Array、 DataModel にバインドさせることができます。
workbook エレメントはコンテナとして動作するため属性はありません。 子エレメントの worksheet には、 データへの EL バインディングとなる value="#{data}" と、 現在のアイテム名となる var="item" の 2 種類の属性があります。worksheet には column が 1 つだけあり、 この中に cell があります。 現在反復しているアイテム内のデータへの最終バインディングとなります。
19.3. workbook リンクのコピーリンクがクリップボードにコピーされました!
<e:workbook>
|
Attributes
子となるエレメント
ファセット
|
19.4. worksheet リンクのコピーリンクがクリップボードにコピーされました!
<e:worksheet>
|
子となるエレメント
ファセット
|
19.5. column リンクのコピーリンクがクリップボードにコピーされました!
<e:column>
|
Attributes
子となるエレメント
ファセット
|
19.6. cell リンクのコピーリンクがクリップボードにコピーされました!
column 属性と row 属性を用いた直接的な配置) にネストされ、 通常データテーブルの var 属性を伴う EL 式でその値の出力を行います。 「セルの設定」 を参照してください。
<e:cell>
|
Attributes
子となるエレメント
ファセット
|
19.6.1. validation リンクのコピーリンクがクリップボードにコピーされました!
<e:numericValidation>
|
Attributes
子となるエレメント
ファセット
|
<e:rangeValidation>
|
Attributes
子となるエレメント
ファセット
|
<e:listValidation>
|
Attributes
子となるエレメント
ファセット
|
<e:listValidationItem>
|
Attributes
子となるエレメント
ファセット
|
19.6.2. 書式マスク リンクのコピーリンクがクリップボードにコピーされました!
mask 属性で定義されます。 書式マスクは数値と日付の 2 種類あります。
19.6.2.1. 数値マスク リンクのコピーリンクがクリップボードにコピーされました!
format1、 accounting_float など、 それが内部書式に従うかどうかがチェックされます (jxl.write.NumberFormats を参照してください)。
0.00 など)、 自動的に一番近いものに変換されます ( java.text.DecimalFormat を参照)。
19.6.2.2. 日付マスク リンクのコピーリンクがクリップボードにコピーされました!
dd.MM.yyyy など)、 自動的に一番近いものに変換されます ( java.text.DateFormat を参照)。
19.7. formula リンクのコピーリンクがクリップボードにコピーされました!
column 属性と row 属性を用いた直接的な配置) にネストされ、 ある範囲のセル値の計算や関数の適用を行います。 formula は本質的にセルのため、 使用可能な属性については 「cell」 を参照してください。 テンプレートを適用することができ、 通常のセルと同様に独自のフォント定義などを持たせることができます。
value 属性内に通常の Microsoft Excel の表記法で配置されます。 クロスシートの formula を行う場合、 worksheet に対してフォーミュラを参照する前にその worksheet が存在していなければなりません。 値は文字列になります。
19.8. image リンクのコピーリンクがクリップボードにコピーされました!
startColumn/startRow 属性とrowSpan/columnSpan 属性を用いた直接的な配置) にネストされます。 span タグはオプションのため省略するとその画像はリサイズされずに挿入されます。
<e:image>
|
Attributes
子となるエレメント
ファセット
|
19.9. hyperlink リンクのコピーリンクがクリップボードにコピーされました!
startColumn/startRow 属性と endColumn/endRow 属性を用いた直接的な配置) にネストされます。 URIにリンクのナビゲーションを追加します。
<e:hyperlink>
|
Attributes
子となるエレメント
ファセット
|
19.11. print area とタイトル リンクのコピーリンクがクリップボードにコピーされました!
<e:printArea>
|
Attributes
子となるエレメント
ファセット
|
19.12. ワークシートコマンド リンクのコピーリンクがクリップボードにコピーされました!
19.12.1. グループ化 リンクのコピーリンクがクリップボードにコピーされました!
<e:groupRows>
|
Attributes
子となるエレメント
ファセット
|
<e:groupColumns>
|
Attributes
子となるエレメント
ファセット
|
19.12.2. 改ページ リンクのコピーリンクがクリップボードにコピーされました!
<e:rowPageBreak>
|
Attributes
子となるエレメント
ファセット
|
19.12.3. 結合 リンクのコピーリンクがクリップボードにコピーされました!
<e:mergeCells>
|
Attributes
子となるエレメント
ファセット
|
19.13. データテーブルエクスポータ リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.excel.excelExporter.export コンポーネントを実行し、 データテーブルの ID を Seam の EL パラメータとして渡すことができます。 たとえば、 次のようなデータテーブルがあるとします。
<h:commandLink value="Export"
action="#{excelExporter.export('theForm:theDataTable')}" />
<h:commandLink value="Export"
action="#{excelExporter.export('theForm:theDataTable')}" />
19.14. フォントとレイアウト リンクのコピーリンクがクリップボードにコピーされました!
styleClass と style のシートで適用することができます。
xls-format-mask:'$;$' などの '' 文字で CSS 文字列をエスケープすることができます。
19.14.1. スタイルシートへのリンク リンクのコピーリンクがクリップボードにコピーされました!
e:link タグによって参照されます。 e:link タグはあたかも workbook タグの子であるかのように文書内に配置されます。
<e:link>
|
Attributes
子となるエレメント
ファセット
|
<e:workbook> <e:link URL="/css/excel.css"/> </e:workbook>
<e:workbook>
<e:link URL="/css/excel.css"/>
</e:workbook>
/css/excel.css で示されるスタイルシートを参照します。
19.14.2. フォント リンクのコピーリンクがクリップボードにコピーされました!
|
xls-font-family
|
フォント名です。 ここに入力したフォントがご使用のシステムによってサポートされていることを確認してください。
|
|
xls-font-size
|
フォントサイズを示す数値です。
|
|
xls-font-color
|
フォントの色です ( jxl.format.Colour を参照)。
|
|
xls-font-bold
|
フォントを太字にするかどうか決める Boolean です。 有効な値は
true と false です。
|
|
xls-font-italic
|
フォントを斜体にするかどうかを決める Boolean です。 有効な値は
true と false です。
|
|
xls-font-script-style
|
フォントの上付きや下付きを設定します ( jxl.format.ScriptStyle を参照)。
|
|
xls-font-underline-style
|
フォントの下線を設定します ( jxl.format.UnderlineStyle を参照)。
|
|
xls-font-struck-out
|
フォントに取り消し線を引くかどうかを決める Boolean です。 有効な値は
true と false です。
|
|
xls-font
|
フォント関連の全ての値の設定を略記で行います。 フォント名を最後にします(フォント名に空白があるフォントを使用する場合は
'Times New Roman' のように一重引用符でそのフォントを囲みます)。ここでは斜体、太字、 取り消し線のテキストは italic、 bold、 struckout で定義します。
例えば、
style="xls-font: red bold italic 22 Verdana"
|
19.14.3. ボーダー リンクのコピーリンクがクリップボードにコピーされました!
|
xls-border-left-color
|
セルの左端ボーダーの色です ( jxl.format.Colour を参照)。
|
|
xls-border-left-line-style
|
セルの左端ボーダーの線スタイルです ( jxl.format.LineStyle を参照)。
|
|
xls-border-left
|
セルの左端ボーダーの色と線スタイルの設定を略記で行います。 例えば
style="xls-border-left: thick red" のようになります。
|
|
xls-border-top-color
|
セルの上端ボーダーの色です ( jxl.format.Colour を参照)。
|
|
xls-border-top-line-style
|
セルの上端ボーダーの線スタイルです ( jxl.format.LineStyle を参照)。
|
|
xls-border-top
|
セルの上端ボーダーの色と線スタイルの設定を略記で行います。 例えば
style="xls-border-top: red thick" のようになります。
|
|
xls-border-right-color
|
セルの右端ボーダーの色です ( jxl.format.Colour を参照)。
|
|
xls-border-right-line-style
|
セルの右端ボーダーの線スタイルです ( jxl.format.LineStyle を参照)。
|
|
xls-border-right
|
セルの右端ボーダーの色と線スタイルの設定を略記で行います。 例えば
style="xls-border-right: thick red" のようになります。
|
|
xls-border-bottom-color
|
セルの下端ボーダーの色です ( jxl.format.Colour を参照)。
|
|
xls-border-bottom-line-style
|
セルの下端ボーダーの線スタイルです ( jxl.format.LineStyle を参照)。
|
|
xls-border-bottom
|
セルの下端ボーダーの色と線スタイルの設定を略記で行います。 例えば
style="xls-border-bottom: thick red" のようになります。
|
|
xls-border
|
セルの上下左右すべてのボーダーの色と線スタイルの設定を略記で行います。 例えば
style="xls-border: thick red" のようになります。
|
19.14.4. 背景 リンクのコピーリンクがクリップボードにコピーされました!
|
xls-background-color
|
背景の色です ( jxl.format.LineStyle を参照)。
|
|
xls-background-pattern
|
背景のパターンです ( jxl.format.Pattern を参照)。
|
|
xls-background
|
背景の色とパターンの設定を略記で行います。
|
19.14.5. 列の設定 リンクのコピーリンクがクリップボードにコピーされました!
|
xls-column-width
|
列の幅です。 約 5000 の値から開始して必要に応じて調整することをお勧めします。 XHTML モードで
e:column により使用されます。
|
|
xls-column-widths
|
各列の幅です。 約 5000 の値から開始して必要に応じて調整することをお勧めします。 Excel エクスポータにより使用され、 データテーブルの
style 属性に置かれます。 数値を使用するか、 列の迂回には「*」を使用してください。
たとえば、
style="xls-column-widths: 5000, 5000, *, 10000"
|
|
xls-column-autosize
|
列のサイズを自動的に決定するかどうかを判断します。 有効な値は
true と false です。
|
|
xls-column-hidden
|
列を非表示にするかどうかを決めます。 有効な値は
true と false です。
|
|
xls-column-export
|
列をエクスポートに表示させるかどうかを決めます。 有効な値は
true と false です。 デフォルトでは true に設定されます。
|
19.14.6. セルの設定 リンクのコピーリンクがクリップボードにコピーされました!
|
xls-alignment
|
セル値のアライメントを行います (jxl.format.Alignment を参照)。
|
|
xls-force-type
|
セルの強制されたデータタイプを決定する文字列値です。 有効な値は
general、 number、 text、 date、 formula、 bool です。 データタイプは自動的に検出されるためこの属性を使うことはまれです。
|
|
xls-format-mask
|
セルのフォーマットマスクです (「書式マスク」 を参照)。
|
|
xls-indentation
|
セルの内容の字下げを決める数値です。
|
|
xls-locked
|
セルをロックするかどうかを設定します。workbook レベルの
locked と併用します。 有効な値は true または false です。
|
|
xls-orientation
|
セル値の方向を設定します ( jxl.format.Orientation を参照)。
|
|
xls-vertical-alignment
|
セル値の垂直方向の配置を設定します ( jxl.format.VerticalAlignment を参照)。
|
|
xls-shrink-to-fit
|
セル値をセルに合わせて縮小するかどうかを設定します。 有効な値は
true と false です。
|
|
xls-wrap
|
セルで新しい行を折り返すかどうかを決めます。 有効な値は
true と false です。
|
19.14.7. データテーブルエクスポータ リンクのコピーリンクがクリップボードにコピーされました!
xls-column-widths 属性を用いて定義されます (UIColumn が style や styleClass の属性をサポートしないためです)。
19.14.8. 制限 リンクのコピーリンクがクリップボードにコピーされました!
.xhtml文書を使用する場合、 スタイルシートは<e:link>タグで参照されなければなりません。- データテーブルエクスポータの場合は、 CSS はスタイルの属性で与えられなければなりません。 外部のスタイルシートはサポートされません。
19.15. 国際化 リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.excel.not_a_number— 数値であると想定された値が、実際にはそうではなかった場合のエラーメッセージです。org.jboss.seam.excel.not_a_date— 日付であると想定された値が、実際にはそうではなかった場合のエラーメッセージです。
19.16. リンクおよびその他のドキュメント リンクのコピーリンクがクリップボードにコピーされました!
注記
第20章 電子メール リンクのコピーリンクがクリップボードにコピーされました!
jboss-seam-mail.jar により提供されます。 この JAR にはメールの作成に使用されるメール JSF コントロール、および mailSession マネージャコンポーネントが含まれます。
examples/mail プロジェクトをご覧ください。 正しいパッケージの方法を示すデモ、 および現在対応している主要な機能が数点含まれています。
20.1. メッセージの作成 リンクのコピーリンクがクリップボードにコピーされました!
<m:message> タグはメッセージ全体を囲み、 Seam に電子メールのレンダリングを開始するよう指示します。 <m:message> タグ内では、 メッセージの送信者の指定に <m:from> タグ、 受信者の指定に <m:to> タグ、さらに <m:subject> タグを使用します (EL は通常の Facelets にあるためそれが使用される点に注意してください)。
<m:body> タグは電子メールの本文を囲みます。 HTML 正規タグを本文内や JSF コンポーネント内に使用することができます。
m:message がレンダリングされると、 mailSession が電子メールを送信するよう呼び出されます。 電子メールを送信するには Seam にそのビューをレンダリングするよう指示します。
20.1.1. 添付ファイル リンクのコピーリンクがクリップボードにコピーされました!
jboss-seam-mail.jar を送信するには
<m:attachment value="/WEB-INF/lib/jboss-seam-mail.jar"/>
<m:attachment value="/WEB-INF/lib/jboss-seam-mail.jar"/>
jboss-seam-mail.jar という名前で添付されますが、 fileName 属性を追加して編集すると添付ファイルの名前を変更することができます。
<m:attachment value="/WEB-INF/lib/jboss-seam-mail.jar"
fileName="this-is-so-cool.jar"/>
<m:attachment value="/WEB-INF/lib/jboss-seam-mail.jar"
fileName="this-is-so-cool.jar"/>
java.io.File、 java.net.URL を添付することもできます。
<m:attachment value="#{numbers}"/>
<m:attachment value="#{numbers}"/>
byte[] あるいは java.io.InputStream
<m:attachment value="#{person.photo}" contentType="image/png"/>
<m:attachment value="#{person.photo}" contentType="image/png"/>
byte[] や java.io.InputStream には添付ファイルの MIME タイプを指定する必要があります。 この情報はファイルの一部とはならないためです。
<m:attachment> タグで囲むことで、Seam 生成の PDF や標準の JSF ビューを添付することができます。
<m:attachment fileName="tiny.pdf">
<p:document>
A very tiny PDF
</p:document>
</m:attachment>
<m:attachment fileName="tiny.pdf">
<p:document>
A very tiny PDF
</p:document>
</m:attachment>
<ui:repeat> を使うことができます。
<ui:repeat value="#{people}" var="person">
<m:attachment value="#{person.photo}" contentType="image/jpeg"
fileName="#{person.firstname}_#{person.lastname}.jpg"/>
</ui:repeat>
<ui:repeat value="#{people}" var="person">
<m:attachment value="#{person.photo}" contentType="image/jpeg"
fileName="#{person.firstname}_#{person.lastname}.jpg"/>
</ui:repeat>
<m:attachment value="#{person.photo}" contentType="image/jpeg"
fileName="#{person.firstname}_#{person.lastname}.jpg"
status="personPhoto" disposition="inline" />
<img src="cid:#{personPhoto.contentId}" />
<m:attachment value="#{person.photo}" contentType="image/jpeg"
fileName="#{person.firstname}_#{person.lastname}.jpg"
status="personPhoto" disposition="inline" />
<img src="cid:#{personPhoto.contentId}" />
cid:#{...} タグはイメージ検索が試行されたときに添付ファイルの検査が行われるよう指定します。 cid — Content-ID — が一致しなければなりません。
20.1.2. HTML /Text 代替部分 リンクのコピーリンクがクリップボードにコピーされました!
20.1.3. 複数の受信者 リンクのコピーリンクがクリップボードにコピーされました!
<ui:repeat> の中に置くことができます。
<ui:repeat value="#{allUsers} var="user">
<m:to name="#{user.firstname} #{user.lastname}"
address="#{user.emailAddress}"/>
</ui:repeat>
<ui:repeat value="#{allUsers} var="user">
<m:to name="#{user.firstname} #{user.lastname}"
address="#{user.emailAddress}"/>
</ui:repeat>
20.1.4. 複数のメッセージ リンクのコピーリンクがクリップボードにコピーされました!
<ui:repeat> 内に配置することです。
20.1.5. テンプレートの作成 リンクのコピーリンクがクリップボードにコピーされました!
template.xhtml には次の内容が含まれています。
templating.xhtml には次の内容が含まれています。
WEB-INF/lib の JAR ファイルに入れて置く必要があります。 Seam Mail を使用する場合は web.xml からの .taglib.xml の参照は信頼性に欠けるためです (非同期でメールを送信すると Seam Mail は JSF あるいは Servelt コンテキストにアクセスできないため、 web.xml の設定パラメータを認識しません)。
20.1.6. 国際化 リンクのコピーリンクがクリップボードにコピーされました!
<m:message charset="UTF-8"> ... </m:message>
<m:message charset="UTF-8">
...
</m:message>
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
20.1.7. その他のヘッダー リンクのコピーリンクがクリップボードにコピーされました!
<m:message xmlns:m="http://jboss.com/products/seam/mail"
importance="low" requestReadReceipt="true"/>
<m:message xmlns:m="http://jboss.com/products/seam/mail"
importance="low" requestReadReceipt="true"/>
<m:header> タグを使うとメッセージにあらゆるヘッダーを追加することができます。
<m:header name="X-Sent-From" value="JBoss Seam"/>
<m:header name="X-Sent-From" value="JBoss Seam"/>
20.2. 電子メールの受信 リンクのコピーリンクがクリップボードにコピーされました!
mail-ra.rar) を提供していますが、以下のように mail-ra.rar を設定することも可能です。
onMessage(Message message) を呼び出します。 ほとんどの Seam アノテーションは MDB の内側で動作しますが、 永続コンテキストにはアクセスしないでください。
20.3. 設定 リンクのコピーリンクがクリップボードにコピーされました!
jboss-seam-mail.jar を WEB-INF/lib ディレクトリに配置してください。 JBoss AS を使用する場合はこれ以上の設定は必要ありません。 JBoss AS を使用しない場合は JavaMail API と Java Activation Framework のコピーがあることを確認してください。 Seam で配信されるバージョンはそれぞれ lib/mail.jar と lib/activation.jar です。
注記
seam-ui パッケージの使用とビューテクノロジーとして Facelets を使用する必要があります。ライブラリの今後のバージョンでは JSP の使用にも対応する可能性があります。
mailSession コンポーネントは「実際の」SMTP サーバと通信するときに JavaMail を使用します。
20.3.1. mailSession リンクのコピーリンクがクリップボードにコピーされました!
mailSession コンポーネントのプロパティについては 「メール関連のコンポーネント」 で詳しく説明しています。
20.3.1.1. JBoss AS の JNDI ルックアップ リンクのコピーリンクがクリップボードにコピーされました!
deploy/mail-service.xml で JNDI にバインドしている JavaMail セッションを設定します。 デフォルトのサービス設定は使用するネットワークに応じて変更する必要があります。 http://wiki.jboss.org/wiki/Wiki.jsp?page=JavaMail でサービスに関する詳細な記載をご覧ください。
<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:mail="http://jboss.com/products/seam/mail">
<mail:mail-session session-jndi-name="java:/Mail"/>
</components>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:mail="http://jboss.com/products/seam/mail">
<mail:mail-session session-jndi-name="java:/Mail"/>
</components>
java:/Mail にバインドされるメールセッションを取得するよう指示します。
20.3.1.2. Seam 設定のセッション リンクのコピーリンクがクリップボードにコピーされました!
components.xml で設定できます。 ここでは smtp.example.com を SMTP サーバーとして使用するよう Seam に指示します。
<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:mail="http://jboss.com/products/seam/mail">
<mail:mail-session host="smtp.example.com"/>
</components>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:mail="http://jboss.com/products/seam/mail">
<mail:mail-session host="smtp.example.com"/>
</components>
20.4. タグ リンクのコピーリンクがクリップボードにコピーされました!
http://jboss.com/products/seam/mail の名前空間内でタグを使って生成されます。 ドキュメントには常にメッセージのルートに message タグがあるはずです。 メッセージタグは Seam による電子メール生成の準備を行います。
body 内ではすべての JSF タグを使用することができます。 スタイルシートや Javascript などの外部リソースへのアクセスがタグに必要な場合は、必ず urlBase を設定してください。
- <m:message>
- メールメッセージのルートタグです。
importance— メールメッセージの重要度を設定します。 有効な値はlow、normal、highです。 デフォルトはnormalです。precedence− メッセージの優先度を設定します (bulkなど)。requestReadReceipt− これを設定すると、受け取り確認が追加されFrom:アドレスに受け取り確認が送信されます。 デフォルトではfalseに設定されています。urlBase− これを設定するとその値がrequestContextPathの前に置かれ、電子メール中に<h:graphicImage>などのコンポーネントを使用できます。messageId− メッセージ ID を明示的に設定します。
- <m:from>
- 電子メールに
From:のアドレスを設定します。1 つの電子メールに対して 1 つのアドレスしか設定できません。name−電子メール発信者の名前です。address− 電子メール発信者のメールアドレスです。
- <m:replyTo>
- 電子メールに
Reply-to:のアドレスを設定します。1 つのメールに対して 1 つのアドレスしか設定できません。address− 電子メール発信者の電子メールアドレスです。
- <m:to>
- 電子メールに受信者を追加します。 受信者が複数の場合は複数の
<m:to>タグを使用します。 このタグは<ui:repeat>などの繰り返しタグ内に安全に配置できます。name− 受信者の名前です。address− 受信者の電子メールアドレスです。
- <m:cc>
- 電子メールに CC の受信者を追加します。 CC が複数の場合は複数の <m:cc> タグを使用します。 このタグは <ui:repeat> などの繰り返しタグ内に安全に配置できます。
name− 受信者の名前です。address− 受信者の電子メールアドレスです。
- <m:bcc>
- 電子メールに BCC の受信者を追加します。 BCC が複数の場合は複数の <m:bcc> タグを使用します。 このタグは <ui:repeat> などの繰り返しタグ内に安全に配置できます。
name− 受信者の名前です。address− 受信者の電子メールアドレスです。
- <m:header>
- 電子メールにヘッダーを追加します (例、
X-Sent-From: JBoss Seam)。name− 追加するヘッダー名です (例、X-Sent-From)。value− 追加するヘッダーの値です (例、JBoss Seam)。
- <m:attachment>
- 電子メールに添付ファイルを追加します。
value− 添付するファイルです。String−Stringはクラスパス内のファイルへのパスと解釈されます。java.io.File− EL 式はFileオブジェクトを参照することができます。java.net.URL− EL 式はURLオブジェクトを参照することができますjava.io.InputStream− EL 式はInputStreamを参照することができます。 この場合fileNameとcontentTypeの両方を指定する必要があります。byte[]− EL 式はbyte[]を参照することができます。 この場合、fileNameとcontentTypeの両方を指定する必要があります。
値属性が省略される場合- このタグに
<p:document>タグが含まれる場合、 記載されたドキュメントが生成され電子メールに添付されます。fileNameを指定してください。 - このタグに他の JSF タグが含まれる場合、そこから HTML ドキュメントが生成され電子メールに添付されます。
fileNameを指定してください。
fileName− 添付ファイルに使用するファイル名を指定します。contentType− 添付ファイルの MIME タイプを指定します。
- <m:subject>
- 電子メールに件名を設定します。
- <m:body>
- 電子メールの本文を設定します。
alternativeファセットに対応します。 HTML 電子メールが生成されると HTML をサポートしていないメールリーダ用に代替となるテキストを含ませることができます。type−plainに設定するとプレーンテキストの電子メールを生成します。 これ以外は HTML 電子メールを生成します。
第21章 非同期性とメッセージング リンクのコピーリンクがクリップボードにコピーされました!
java.util.concurrent.ScheduledThreadPoolExecutor(デフォルト)- EJB タイマーサービス (EJB 3.0 環境向け)
- Quartz
21.1. 非同期性 リンクのコピーリンクがクリップボードにコピーされました!
ScheduledThreadPoolExecutor をベースとするデフォルトのディスパッチャは効率的な働きをしますが、 永続非同期のタスクに対応していないためタスクが実際に実行されるかは保証されません。 EJB 3.0 に対応する環境で作業している場合は次の行を components.xml に追加して、 コンテナの EJB タイマーサービスによりタスクが非同期に処理されるようにします。
<async:timer-service-dispatcher/>
<async:timer-service-dispatcher/>
EAR に Quartz ライブラリ JAR (lib ディレクトリ) を同梱してから application.xml で Java モジュールとして宣言します。 Quartz ディスパッチャはクラスパスに Quartz プロパティファイルを追加すると設定可能になります。このファイルは seam.quartz.properties という名前にしてください。 また、 Quartz ディスパッチャをインストールする場合は次の行を components.xml に追加する必要があります。
<async:quartz-dispatcher/>
<async:quartz-dispatcher/>
Scheduler、 EJB3 Timer、 デフォルトの ScheduledThreadPoolExecutor の Seam API は非常によく似ているため、 components.xml に 1 行追加するだけで「プラグアンドプレイ」が可能です。
21.1.1. 非同期メソッド リンクのコピーリンクがクリップボードにコピーされました!
@Duration、 @Expiration、 @IntervalDuration のアノテーションを使って非同期メソッドの呼び出しをスケジュールすることができます。
Timer オブジェクトにアクセスすることができます。 以下に示す Timer オブジェクトは EJB3 ディスパッチャで使用される EJB3 タイマーです。 デフォルトの ScheduledThreadPoolExecutor の場合、 タイマーは JDK から Future を返します。 Quartz ディスパッチャの場合は QuartzTriggerHandle を返します。 これについては次項で説明していきます。
21.1.2. Quartz ディスパッチャを使った非同期メソッド リンクのコピーリンクがクリップボードにコピーされました!
@Asynchronous、 @Duration、 @Expiration、 @IntervalDuration のアノテーションが使用できます。 また、 他にもいくつかのアノテーションに対応しています。
@FinalExpiration アノテーションは反復タスクの終了日を指定します。 QuartzTriggerHandle をインジェクトできる点に注意してください。
QuartzTriggerHandle オブジェクトを返し、 これを使用してスケジューラの停止、 一時停止、 再開を行うことができます。 QuartzTriggerHandle オブジェクトはシリアライズ可能であるため、 長期間に渡りこれを維持する必要がある場合はデータベースに保存することができます。
@IntervalCron アノテーションはタスクのスケジューリングに Unix cron ジョブ構文をサポートします。 たとえば、 次の非同期メソッドは 3 月の毎水曜日の 2:10pm と 2:44pm に実行されます。
@IntervalBusinessDay アノテーションは「第X日営業日」というシナリオの呼び出しに対応します。 たとえば、 次の非同期メソッドは毎月第2営業日の 14:00 に実行されます。 デフォルトではすべての週末とアメリカ合衆国の祝日を営業日から除外します。
NthBusinessDay オブジェクトには呼び出しトリガーの設定が含まれます。 additionalHolidays プロパティで祝日を追加指定することができます (会社固有の休み、 アメリカ合衆国の祝日以外など)。
@IntervalDuration、 @IntervalCron、 @IntervalNthBusinessDay のアノテーションは互いに矛盾します。 同じメソッド内で使用しようとすると RuntimeException エラーの原因になります。
21.1.3. 非同期イベント リンクのコピーリンクがクリップボードにコピーされました!
Events クラスの raiseAsynchronousEvent() メソッドを呼び出します。 指定時刻に起きるイベントをスケジュールするには、raiseTimedEvent() メソッドを呼び出し、スケジュールオブジェクトを渡します (デフォルトのディスパッチャまたはタイマーサービスのディスパッチャの場合は TimerSchedule を使用します)。 コンポーネントは通常通りに非同期のイベントを監視することができますが、 非同期スレッドに伝播されるのはビジネスプロセスコンテキストのみです。
21.1.4. 非同期の呼び出しによる例外処理 リンクのコピーリンクがクリップボードにコピーされました!
java.util.concurrent は繰り返す呼び出しの実行がこれ以上起きないよう一時停止し、EJB3 タイマーサービスがその例外を吸収します。 したがって、 非同期の呼び出しから伝播する例外がディスパッチャに到達する前に Seam によってその例外はキャッチされます。
org.jboss.seam.async.asynchronousExceptionHandler コンポーネントを無効にするとこの動作をグローバルにカスタマイズすることができます。
java.util.concurrent ディスパッチャを使ってその制御オブジェクトをインジェクトし、例外が送出された場合には今後の呼び出しをすべて取り消すようにしています。
public void handleAsynchronousException(Exception exception); メソッドを実装すると個別のコンポーネントに対しこの動作を変更することができます。 たとえば、
public void handleAsynchronousException(Exception exception) {
log.fatal(exception);
}
public void handleAsynchronousException(Exception exception) {
log.fatal(exception);
}
21.2. Seam でのメッセージング リンクのコピーリンクがクリップボードにコピーされました!
21.2.1. 設定 リンクのコピーリンクがクリップボードにコピーされました!
QueueConnectionFactory や TopicConnectionFactory の場所を指示する必要があります。
UIL2ConnectionFactory を使用します。 別の JMS プロバイダを使用する場合は、 seam.properties、 web.xml、 components.xml のいずれかで queueConnection.queueConnectionFactoryJndiName と topicConnection.topicConnectionFactoryJndiName の一方あるいは両方を設定する必要があります。
TopicPublisher と QueueSender をインストールするには、components.xml にトピックとキューも記載する必要があります。
21.2.2. メッセージ送信 リンクのコピーリンクがクリップボードにコピーされました!
TopicPublisher と TopicSession をコンポーネントにインジェクトすることができます。
21.2.3. メッセージ駆動型 Bean を使用したメッセージの受信 リンクのコピーリンクがクリップボードにコピーされました!
注記
@In アノテーションで create 属性を true に設定する必要がある場合があります。 これにより Seam はインジェクトされるコンポーネントのインスタンスを作成できます (コンポーネントが自動作成に対応しない場合にのみ必要となります。 つまり、 @Autocreate アノテーションが付与されません)。
21.2.4. クライアントでのメッセージの受信 リンクのコピーリンクがクリップボードにコピーされました!
第22章 キャッシュ リンクのコピーリンクがクリップボードにコピーされました!
- データベース用のキャッシュを持っています。これは非常に重要ですが、アプリケーション層のキャッシュのような拡張性はありません。
- ORM ソリューション (Hibernate または別の JPA 実装) で提供されるデータベースの 2 次データキャッシュがあります。 クラスタ環境でキャッシュデータをデータベースおよびその他のクラスタの両方とトランザクション的な永続性を持たせるのは、 効率的な実装を行うという点で非常にコスト高となる場合があります。 したがって、 この 2 次キャッシュにはほとんど更新されることがないデータを格納するための使用と多くのユーザーとの共有に最適となります。 従来のステートレスなアーキテクチャでは、この空間は対話的な状態の保存によく使用されます (非効率的)。
- 対話状態のキャッシュとなる Seam の対話コンテキストです。対話コンテキスト内のコンポーネントは、 現在のユーザーのインタラクションに関連した状態を保持します。
- Seam 管理永続コンテキストは現在の対話に読み込まれたデータのキャッシュとして動作します (対話スコープのステートフルセッション Bean に関連付けられた EJB コンテナ管理の永続コンテキストを、Seam 管理永続コンテキストの代わりに使用することが可能です)。Seam によりクラスタ環境で Seam 管理永続コンテキストの複製が最適化され、楽観的ロック機能によりデータベースに一貫性のあるトランザクションを提供します。1 つの永続コンテキストに何千ものオブジェクトを読み込まない限り、このキャッシュによるパフォーマンスに及ぶ影響は最小限となります。
- Seam のアプリケーションコンテキストを使用するとトランザクションでない状態をキャッシュすることができます。 ここに保持される状態はクラスタ内の他のノードからは見えません。
- アプリケーション内の Seam
cacheProviderコンポーネントは、JBossCache または Ehcache を Seam 環境に統合します。キャッシュがクラスタモード内での実行をサポートする場合は、ここに保持される状態は他のノードにも見えます。 - 最後に、 レンダリングされた JSF ページの断片をキャッシュすることができます。 ORM の 2 次キャッシュと違い、 データが更新されたときに自動的に無効にはならないため、 明示的に無効化するアプリケーションコードを書くか、 適切な有効期限ポリシーを設定する必要があります。
cacheProvider コンポーネントを使用し直接キャッシュを行う方法、 または <s:cache> コントロールを使用し保存されたページ断片としてキャッシュする方法について説明します。
22.1. Seam でのキャッシュの使用 リンクのコピーリンクがクリップボードにコピーされました!
cacheProvider コンポーネントは以下のインスタンスを管理します。
- JBoss Cache 3.2.x
org.jboss.cache.Cache- EhCache
net.sf.ehcache.CacheManager
cacheProvider を使うには、 プロジェクトにキャッシュ実装に関する JAR を含ませる必要があります。
- JBoss Cache 3.2.x
jbosscache-core.jar— JBoss Cache 3.2.xjgroups.jar— JGroups 2.6.x
- Ehcache
ehcache.jar— Ehcache 1.2.3
EAR デプロイメントでは、キャッシュ JAR と設定は直接 EAR に行くことが推奨されます。
cache-configuration.xml をクラスパスに置きます。例えば、EJB JAR または WEB-INF/classes です。JBossCache の設定に関する詳細は、JBossCache の文書を参照してください。
cache-configuration.xml は examples/blog/resources/META-INF/cache-configuration.xml にあります。
components.xmlでキャッシュの設定を行います。
components.xml を使用して複数のキャッシュプロバイダを設定します。
22.2. ページ断片のキャッシュ リンクのコピーリンクがクリップボードにコピーされました!
<s:cache> タグが JSF におけるページ断片のキャッシュに関する問題を解決してくれます。 <s:cache> は pojoCache を内部的に使用するため前述の手順を行っておく必要があります。 JAR を EAR に配置してから追加の設定オプションを編集します。 これで使用できるようになります。
<s:cache> はあまり更新のないレンタリングされたコンテンツを保存します。 たとえば、 ブログのウェルカムページでは最新のブログエントリが表示されます。
key を指定することによって各ページ断片の複数のバージョンを保存することができます。 この例では、 1 ブログに対して 1 キャッシュバージョンが存在します。 region には、すべてのバージョンを保存するキャッシュまたは領域ノードを指定します。異なるノードは異なる有効期限ポリシーを持つ場合があります。
<s:cache> の問題は基礎的データがいつ更新されるか認識できないことです。 このため、 変更が発生した場合はキャッシュされた断片を手作業で削除する必要があります。
第23章 Web サービス リンクのコピーリンクがクリップボードにコピーされました!
23.1. 設定とパッケージング リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.webservice.SOAPRequestHandler は SOAPHandler の実装であり、 Web サービス要求のスコープの間 Seam コンポーネントのライフサイクルを管理します。
standard-jaxws-endpoint-config.xml (設定ファイル) は、Web サービスクラスを含む JAR ファイルの META-INF ディレクトリに配置されるはずです。 このファイルには以下のような SOAP ハンドラの設定が含まれています。
23.2. 対話型 Web サービス リンクのコピーリンクがクリップボードにコピーされました!
conversationId エレメントが含まれ、 要求の対話 ID を含んでいます。 この例の場合は 2 です。 Web サービスを使う Web サービスのクライアントは多種多様で、なおかつさまざまな言語で記述されているため、 ひとつの対話のスコープ内で使われるそれぞれの Web サービス間の対話 ID の伝播を実装するのは開発者の責任となります。
conversationId ヘッダーエレメントは http://www.jboss.org/seam/webservice の名前空間に適したものでなければいけません。 そうでないと、 Seam はその要求から対話 ID を読み取ることができなくなります。 上記の要求メッセージに対する応答の例を示します。
conversationId エレメントが含まれているので留意してください。
23.2.1. 推奨される方法 リンクのコピーリンクがクリップボードにコピーされました!
@Name アノテーションを付与することで Seam コンポーネントに変換することも可能です。 これにより Web サービスのクラス自体で Seam のバイジェクションやその他の機能を使用することができます。
23.3. Web サービスの例 リンクのコピーリンクがクリップボードにコピーされました!
/examples ディレクトリにあり、前項で述べた推奨される方法に添っています。 まず、 Web サービスのクラスとその Web サービスのメソッドから見てみましょう。
javax.jws パッケージの JWS アノテーションが付与されたステートレスセッション Bean です。@WebService アノテーションがコンテナにこのクラスが Web サービスを実装することを伝えます。login() メソッドにある @WebService アノテーションはメソッドを Web サービスメソッドとして識別します。 @WebService アノテーションの name と serviceName の属性はオプションです。
AuctionServiceRemote インターフェースが @WebMethod でアノテーションが付与されているため、 login() メソッドを宣言しなければなりません。
Identity コンポーネントに委譲する login() メソッドを実装します。 推奨方法で提示しているように、 Web サービスは単にファサードとして記述されています。 実際の作業は Seam コンポーネント内で行われます。 つまり、 Web サービスと他のクライアント間でビジネスロジックは効率的に再利用されるということです。
AuctionAction.createAuction() メソッドに委譲することで新しい対話を開始しています。
AuctionAction からのコードです。
23.4. RESTEasy を使用した RESTful HTTP Web サービス リンクのコピーリンクがクリップボードにコピーされました!
- RESTEasy ブートストラップと設定、リソースの自動削除、およびプロバイダ
- SeamResourceServlet による HTTP/REST 要求、
web.xmlでの外部のサーブレットおよび設定の必要性はなし - Seam コンポーネントとしてのリソースの記述、Seam の完全なライフサイクルの管理とバイジェクション
23.4.1. RESTEasy 設定と要求 リンクのコピーリンクがクリップボードにコピーされました!
jaxrs-api.jar をダウンロードします。それらを統合ライブラリ (jboss-seam-resteasy.jar) やご使用のアプリケーションに必要な他のライブラリとともにデプロイします。
jaxrs-api.jar、resteasy-jaxrs.jar、および jboss-seam-resteasy.jar を deployed-jars.list (war デプロイメント) または deployed-jars-ear.list (ear デプロイメント) ファイルに追加することによって行えます。JBDS ベースのプロジェクトの場合は、上記のライブラリを EarContent/lib (ear デプロイメント) または WebContent/WEB-INF/lib (war デプロイメント) フォルダにコピーし、IDE でプロジェクトをリロードします。
@javax.ws.rs.Path でアノテーション付与されたすべてのクラスは、起動時に自動的に発見され HTTP リソースとして登録されます。Seam は 組み込みSeamResourceServlet を使って自動的に HTTP 要求を受け入れ、提供します。リソースの URI は以下のように構築されます。
- URI は例として
/seam/resourceのSeamResourceServletのweb.xmlでマップされたパターンで始まります。この設定を変更して、異なるベースでご使用の RESTful リソースを公開します。これは グローバルな 変更で、他の Seam リソース (s:graphicImage) もこのベースパスで提供されます。 - Seam の RESTEasy 統合ではベースパスに設定可能な文字列を追加します (デフォルトは
/rest)。このため、サンプルではリソースの完全なベースパスは/seam/resource/restとなるでしょう。今後の REST API のアップグレードに備えてバージョン番号を追加するなど、ご使用のアプリケーションのこの文字列をさらに記述的なものに変更することをお薦めします。これにより旧のクライアントは旧の URI ベースを維持することができます。 - 最後に、リソースは定義された
@Pathで使用可能です。たとえば、@Path("/customer")でマップされたリソースは、/seam/resource/rest/customerで使用可能となります。
http://your.hostname/seam/resource/rest/customer/123 を使用した GET 要求に対するプレーンテキスト表現を返します。
resteasy 名前空間を XML 設定ファイルのヘッダーにインポートします。
<resteasy:application resource-path-prefix="/restv1"/>
<resteasy:application resource-path-prefix="/restv1"/>
/seam/resource/restv1/{resource} です。@Path の定義とマッピングは変わらない点に注意してください。これはアプリケーション全体に及ぶスイッチであり、通常は HTTP API のバージョニングに使用されます。
<resteasy:application strip-seam-resource-path="false"/>
<resteasy:application strip-seam-resource-path="false"/>
@Path("/seam/resource/rest/customer") にマップされました。この機能を無効にすることで、リソースクラスのマッピングを特定のデプロイメントシナリオにバインドします。これは 推奨されません。
@javax.ws.rs.Path リソースまたは @javax.ws.rs.ext.Provider クラスにスキャンします。以下のようにスキャンを無効にして、これらのクラスを手動で設定することが可能です。
use-built-in-providers のスイッチは RESTEasy 組み込みプロバイダを有効 (デフォルト) または無効にします。これらはプレーンテキスト、JSON および JAXB マーシャリングを提供するため、有効にしておくことが推奨されます。
web.xml で移植可能でない方法で JNDI の名前を設定する代わりに (RESTEasy のドキュメントを参照)、上記に示したとおり components.xml でビジネスインターフェースではなく、単純に EJB 実装クラスを一覧にすることができます。EJB の @Local インターフェースに Bean 実装クラスではなく @Path、@GET などでアノテーションを付与する必要がある点に注意してください。これによりご使用のアプリケーションをグローバルな Seam jndi-pattern のスイッチをオン <core:init/> にした状態で、デプロイメントで移植可能に保つことができます。純粋な (Seam コンポーネントでない) EJB リソースはリソースのスキャンが有効であっても見つからず、常に手動で一覧化する必要がある点に注意してください。繰り返しになりますが、このパラグラフ全体は Seam コンポーネントでなく、かつ @Name アノテーションを持っていない EJB リソースに関連しているだけです。
.txt.deutsch の URI サフィックスを追加の Accept、Accept-Language ヘッダーの値、text/plain、de-DE にマップします。
23.4.2. Seam コンポーネントとしてのリソースとプロバイダ リンクのコピーリンクがクリップボードにコピーされました!
customerResource インスタンスは、要求がサーバーに到達したときに Seam により処理されます。このコンポーネントはイベントスコープであるため、そのライフサイクルは JAX-RS のライフサイクルとまったく同じです。ただし、Seam JavaBean コンポーネントはインジェクションに完全に対応しており、他のすべてのコンポーネントとコンテキストに完全にアクセスすることができます。セキュリティ、アプリケーション、ステートレスなリソースコンポーネントもまた対応しています。これら 3 つのスコープにより、ステートレスな Seam の中間層の HTTP 要求処理アプリケーションを効果的に作成できます。
SESSION スコープの Seam コンポーネントを使用できます。ただしデフォルトでは、セッションは短くなり単一の要求となります。言い換えると HTTP 要求が RESTEasy 統合コードにより処理されている場合、HTTP セッションが作成されるため Seam コンポーネントはそのコンテキストを活用できます。要求が処理されたら、Seam はセッションを調べて、セッションがその単一の要求を提供するためだけに作成されたかを決定します (要求を持つセッション識別子はありません。要求のために存在したセッションもありません)。セッションがこの要求のためだけに作成された場合は、このセッションは要求後に破棄されます。
<resteasy:application destroy-session-after-request="false"/>
<resteasy:application destroy-session-after-request="false"/>
Session.instance().invalidate() によりコード内でタイムアウトまたは明示的な無効化によってのみ削除される新しいセッションを作成します。要求全体に渡りセッションコンテキストを活用したい場合は、HTTP 要求とともに有効なセッション識別子を渡すことはご自身の責任となります。
STATELESS である必要があります。
注記
src/hot フォルダーに置かないでください。代わりに src/main フォルダーを使用してください。
注記
23.4.3. リソースをセキュアにする リンクのコピーリンクがクリップボードにコピーされました!
components.xml で HTTP ベーシック認証およびダイジェスト認証に対し Seam 認証フィルタを有効にできます。
<web:authentication-filter url-pattern="/seam/resource/rest/*" auth-type="basic"/>
<web:authentication-filter url-pattern="/seam/resource/rest/*" auth-type="basic"/>
@Restrict および @PermissionCheck のアノテーションを使用した承認ルールが有効になります。クライアント Identity へのアクセス、パーミッションマッピングとの連携などが可能です。承認に関するすべての Seam が持つ通常のセキュリティ機能は使用可能です。
23.4.4. HTTP 応答への例外のマップ リンクのコピーリンクがクリップボードにコピーされました!
pages.xml 内の HTTP 応答コードに例外をマップすることが可能です。pages.xml をすでに使用している場合は、これは多くの JAX RS 例外のマッパークラスよりも維持し易いです。
web.xml のすべての要求をフィルタする必要があります。次のサンプルはすべての HTTP 要求をインターセプトし、Seam 例外処理を有効にします。
UnsupportedOperationException を 501 Not Implemented HTTP ステータス応答に変換するには、次を pages.xml 記述子に追加します。
<exception class="java.lang.UnsupportedOperationException">
<http-error error-code="501">
<message>The requested operation is not supported</message>
</http-error>
</exception>
<exception class="java.lang.UnsupportedOperationException">
<http-error error-code="501">
<message>The requested operation is not supported</message>
</http-error>
</exception>
<exception class="my.CustomException" log="false">
<http-error error-code="503">
<message>Service not available: #{org.jboss.seam.handledException.message}</message>
</http-error>
</exception>
<exception class="my.CustomException" log="false">
<http-error error-code="503">
<message>Service not available: #{org.jboss.seam.handledException.message}</message>
</http-error>
</exception>
pages.xml の競合する例外マッピングに注意する必要があります。
web.xml 設定に <error-page> マッピングがある場合は、追加のマッピングを適用することが可能です。次に HTTP ステータスコードは 200 OK のステータスを持つレンダリングされた HTML エラーページにマップされます。
23.4.5. RESTful API によるエンティティの公開 リンクのコピーリンクがクリップボードにコピーされました!
ResourceHome と ResourceQueryを提供します。これは Seam Application Framework (13章Seam アプリケーションフレームワーク) により提供された API から利点を受けています。これらのコンポーネントにより、ドメインモデルエンティティクラスを HTTP API にバインドすることができます。
23.4.5.1. ResourceQuery リンクのコピーリンクがクリップボードにコピーされました!
<resteasy:resource-query path="/user" name="userResourceQuery" entity-class="com.example.User"/>
<resteasy:resource-query
path="/user"
name="userResourceQuery"
entity-class="com.example.User"/>
- コンポーネントは
com.example.Userインスタンスの一覧を返します。 - コンポーネントは URI パス
/userの HTTP 要求を処理します。 - コンポーネントはデフォルトではデータを (クライアントの好みに基づき) XML または JSON に変換します。対応する MIME タイプのセットは
media-types属性を使用して変更できます。例えば以下のとおりです。
<resteasy:resource-query path="/user" name="userResourceQuery" entity-class="com.example.User" media-types="application/fastinfoset"/>
<resteasy:resource-query
path="/user"
name="userResourceQuery"
entity-class="com.example.User"
media-types="application/fastinfoset"/>
@Name("userResourceQuery")
@Path("user")
public class UserResourceQuery extends ResourceQuery<User>
{
}
@Name("userResourceQuery")
@Path("user")
public class UserResourceQuery extends ResourceQuery<User>
{
}
| パラメータの名前 | 例 | 詳細 |
|---|---|---|
| start | /user?start=20 | 20 番目のエントリで始まるデーターベースクエリの結果のサブセットを返します。 |
| show | /user?show=10 | 10 エントリに制限されたデーターベースクエリの結果のサブセットを返します。 |
/user?start=30&show=10 に送り、行 30 で始まる 10 行を表すエントリの一覧を取得します。
注記
@XMLRootElement でエンティティクラスにアノテーションを付与する必要があります。詳細は JAXB および RESTEasy のドキュメントを参照してください。
23.4.5.2. ResourceHome リンクのコピーリンクがクリップボードにコピーされました!
| HTTP メソッド | パス | 機能 | ResourceHome メソッド |
|---|---|---|---|
| GET | {path}/{id} | 読み取り | getResource() |
| POST | {path} | 作成 | postResource() |
| PUT | {path}/{id} | 更新 | putResource() |
| DELETE | {path}/{id} | 削除 | deleteResource() |
- HTTP 要求を /user/{userId} に送ることで、特定のユーザーインスタンスを「GET」、「PUT」、「DELETE」できます。
- POST 要求を
/userに送ることで、新しいユーザーエンティティインスタンスを作成、永続化します。通常はそれを永続層に任せて、識別子値、URI が付いたエンティティインスタンスを提供します。そのため URI は HTTP レスポンスのヘッダーLocationのクライアントに送られます。
<resteasy:resource-home
path="/user"
name="userResourceHome"
entity-home="#{userHome}"
entity-id-class="java.lang.Integer"/>
<resteasy:resource-home
path="/user"
name="userResourceHome"
entity-home="#{userHome}"
entity-id-class="java.lang.Integer"/>
23.4.6. リソースとプロバイダのテスト リンクのコピーリンクがクリップボードにコピーされました!
SeamTest クラスを通常どおり拡張し、ResourceRequestEnvironment.ResourceRequest を使用して HTTP 要求 / 応答サイクルをエミュレートします。
SeamResourceServlet と通信しません。モック要求は Seam サーブレットに渡されフィルタされて、そのレスポンスはテストアサーションのために使用可能となります。ResourceRequestEnvironment の共有インスタンスの getDefaultHeaders() メソッドを上書きすることで、テストクラスの各テストメソッドに対して要求ヘッダーを設定できます。
ResourceRequest は @Test メソッドまたは @BeforeMethod コールバックで実行する必要があります。@BeforeClass のような他のコールバックでは実行できません。
第24章 リモーティング リンクのコピーリンクがクリップボードにコピーされました!
24.1. 設定 リンクのコピーリンクがクリップボードにコピーされました!
web.xml ファイル内で Seam Resource Servlet を設定する必要があります。
<script type="text/javascript"
src="seam/resource/remoting/resource/remote.js">
</script>
<script type="text/javascript"
src="seam/resource/remoting/resource/remote.js">
</script>
@Name("customerAction") アノテーションをステートレスセッション Bean に付与する場合、 スクリプトタグは以下のようになります。
<script type="text/javascript"
src="seam/resource/remoting/interface.js?customerAction">
</script>
<script type="text/javascript"
src="seam/resource/remoting/interface.js?customerAction">
</script>
<script type="text/javascript"
src="seam/resource/remoting/interface.js?customerAction&accountAction">
</script>
<script type="text/javascript"
src="seam/resource/remoting/interface.js?customerAction&accountAction">
</script>
s:remote タグを使用することもできます。 インポートしたいコンポーネントやクラス名はそれぞれコンマで区切ります。
<s:remote include="customerAction,accountAction"/>
<s:remote include="customerAction,accountAction"/>
24.2. Seam オブジェクト リンクのコピーリンクがクリップボードにコピーされました!
remote.js で定義される Seam Javascript オブジェクトで行われます。 コンポーネントに対する非同期呼び出しに使用されます。 オブジェクトはコンポーネントと連携するメソッドを含む Seam.Component そしてリモート要求を実行するメソッドを含む Seam.Remoting の 2 つの機能に区分されます。 このオブジェクトに精通する最も容易な方法は簡単なサンプルから始めることです。
24.2.1. Hello World サンプル リンクのコピーリンクがクリップボードにコピーされました!
手順24.1 Hello World の例
Seamオブジェクトがどのように動作するかを見るために、 まずhelloActionと呼ばれる新しい Seam コンポーネントを作成します。Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 新しいコンポーネント用にローカルのインターフェースも生成する必要があります。
@WebRemoteアノテーションはリモーティングでメソッドへのアクセスを可能にするために必要となるので特に注意してください。Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 記述する必要があるサーバー側のコードはこれだけです。次に新しい Web ページを作成して
helloActionコンポーネントをインポートします。<s:remote include="helloAction"/>
<s:remote include="helloAction"/>Copy to Clipboard Copied! Toggle word wrap Toggle overflow - このページにボタンを追加して対話式のユーザーエクスペリエンスにします。
<button onclick="javascript:sayHello()">Say Hello</button>
<button onclick="javascript:sayHello()">Say Hello</button>Copy to Clipboard Copied! Toggle word wrap Toggle overflow - また、 ボタンをクリックしたときに動作を実行するスクリプトが必要になります。
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - アプリケーションをデプロイしてページを見てみます。 ボタンをクリックしてプロンプトが出たら名前を入力します。 呼び出しが成功であることを確認する「Hello」メッセージがメッセージボックスに表示されます (Seam の
/examples/remoting/helloworldディレクトリにこの Hello World サンプルの全ソースコードがあります)。
Seam.Component.getInstance("helloAction").sayHello(name, sayHelloCallback);
Seam.Component.getInstance("helloAction").sayHello(name, sayHelloCallback);
Seam.Component.getInstance("helloAction")) は helloAction コンポーネントのプロキシまたは スタブ を返します。 この行の残りの部分 (sayHello(name, sayHelloCallback);) はスタブに対してコンポーネントのメソッドを呼び出します。
sayHello メソッドを呼び出し、 パラメータとして name を渡しています。2 番目のパラメータ sayHelloCallback はこのコンポーネントの sayHello メソッドのパラメータではありません。 Seam Remoting フレームワークは、要求に対する応答を受けたらそれを sayHelloCallback Javascript メソッドに渡されるべきことを指示しています (このコールバックパラメータはオプションとなるため、 void 戻りタイプでメソッドを呼び出している場合、または要求の結果を気にする必要がない場合は、 そのままにしておいて構いません)。
sayHelloCallback メソッドがリモート要求に対する応答を受け取ると、メソッド呼び出しの結果を表示する警報メッセージを表示します。
24.2.2. Seam.Component リンクのコピーリンクがクリップボードにコピーされました!
Seam.Component Javascript オブジェクトは Seam コンポーネントと連携するクライアント側メソッドをいくつか提供します。 主となる 2 つのメソッド、 newInstance() と getInstance() については本項の後半で詳しく記載しています。 newInstance() は常にコンポーネントタイプの新しいインスタンスを作成し、 getInstance() はシングルトンのインスタンスを返すことが主な違いとなります。
24.2.2.1. Seam.Component.newInstance() リンクのコピーリンクがクリップボードにコピーされました!
var customer = Seam.Component.newInstance("customer");
var customer = Seam.Component.newInstance("customer");
customer.setFirstName("John"); // Or you can set the fields directly
// customer.lastName = "Smith";
customer.setFirstName("John"); // Or you can set the fields directly
// customer.lastName = "Smith";
24.2.2.2. Seam.Component.getInstance() リンクのコピーリンクがクリップボードにコピーされました!
getInstance() メソッドを使って Seam セッション Bean コンポーネントのスタブを参照します。 次にこれを使ってコンポーネントに対して遠隔的にメソッドを実行することができます。 このメソッドは指定コンポーネントのシングルトンを返すため、 続けて同じコンポーネント名で 2 回呼び出すとそのコンポーネントの同じインスタンスが返されます。
customer を作成し保存したい場合は、customerAction コンポーネントの saveCustomer() メソッドにそれを渡します。
Seam.Component.getInstance("customerAction").saveCustomer( customer);
Seam.Component.getInstance("customerAction").saveCustomer( customer);
24.2.2.3. Seam.Component.getComponentName() リンクのコピーリンクがクリップボードにコピーされました!
null を返します。
if (Seam.Component.getComponentName(instance) == "customer")
alert("Customer");
else if (Seam.Component.getComponentName(instance) == "staff")
alert("Staff member");
if (Seam.Component.getComponentName(instance) == "customer")
alert("Customer");
else if (Seam.Component.getComponentName(instance) == "staff")
alert("Staff member");
24.2.3. Seam.Remoting リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting オブジェクト内に含まれます。 そのメソッドの多くは直接呼び出す必要はないはずですが、 言及する価値のある重要なものがいくつかあります。
24.2.3.1. Seam.Remoting.createType() リンクのコピーリンクがクリップボードにコピーされました!
createType() メソッドを使用します。 パラメータとして、完全修飾の Java クラス名を渡してください。
var widget = Seam.Remoting.createType("com.acme.widgets.MyWidget");
var widget = Seam.Remoting.createType("com.acme.widgets.MyWidget");
24.2.3.2. Seam.Remoting.getTypeName() リンクのコピーリンクがクリップボードにコピーされました!
Seam.Component.getComponentName() と同等となる非コンポーネントです。 オブジェクトインスタンスにタイプの名前を返します。 または、 タイプが既知でない場合は null を返します。 この名前は、タイプの Java クラス完全修飾名です。
24.3. EL 式の評価 リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting.eval() 関数を使用して EL 式をサーバー上で遠隔に評価してその結果値をクライアント側のコールバックメソッドに返すことができます。 この関数は 2 つのパラメータを受け取ります。1 番目のパラメータは評価対象となる EL 式であり、2番目のパラメータはその式の値を付けて呼び出すコールバックメソッドです。 次に例を示します。
#{customers} の式が Seam によって評価され、 その式の値 (この場合 Customer オブジェクトの一覧) がcustomersCallback() メソッドに返されます。 このようにして返されるオブジェクトは Javascript で動作できるよう s:remote でそれ自体のタイプがインポートされていなければなりません。 customer オブジェクトの一覧と動作させるには、 customer タイプをインポートする必要があります。
<s:remote include="customer"/>
<s:remote include="customer"/>
24.4. クライアントのインタフェース リンクのコピーリンクがクリップボードにコピーされました!
seam/resource/remoting/interface.js タグまたは s:remote タグのいずれかを使用してページにインポートされます。
<script type="text/javascript"
src="seam/resource/remoting/interface.js?customerAction">
</script>
<script type="text/javascript"
src="seam/resource/remoting/interface.js?customerAction">
</script>
<s:remote include="customerAction"/>
<s:remote include="customerAction"/>
@WebRemote アノテーションが付く場合、 実行可能なスタブが生成されます。 これにより、 セッション Bean にアクセスできない非 EJB 環境で JavaBean コンポーネントのメソッドを呼び出すことができるようになります。
24.5. コンテキスト リンクのコピーリンクがクリップボードにコピーされました!
24.5.1. 対話 ID の設定と読み込み リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting.getContext().getConversationId() を呼び出します。 要求の前に対話 ID を設定する場合には、 Seam.Remoting.getContext().setConversationId() を呼び出します。
Seam.Remoting.getContext().setConversationId() で設定されない場合、 リモート呼び出しによって返される最初の有効な対話 ID が自動的に割り当てられます。 ページ内で複数の対話を使用する場合は、 それぞれの呼び出しの前に対話 ID を明示的に設定する必要があるかもしれません。1 つの対話だけを使用する場合は、明示的に ID を設定する必要はありません。
24.5.2. 現在の対話スコープ内のリモート呼び出し リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting.getContext().setConversationId( #{conversation.id} );
Seam.Remoting.getContext().setConversationId( #{conversation.id} );
24.6. バッチ要求 リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting.startBatch() メソッドは新しいバッチを起動します。 バッチ起動後に実行されるコンポーネント呼び出しはすべて待ち行列に入れられ、 即時送信は行われません。 必要とされるすべてのコンポーネント呼び出しがバッチに追加されると、 Seam.Remoting.executeBatch() メソッドは待ち行列にあるすべての呼び出しを含む単一の要求をサーバーに送信し、 その呼び出しは順番に実行されることになります。 呼び出しが実行されるとすべての戻り値を含む単一の応答がクライアントに返され、 コールバック機能が実行と同じ順番で起動されます。
Seam.Remoting.cancelBatch() メソッドは待ち行列に入れられたすべての呼び出しを破棄してそのバッチモードを終了します。
/examples/remoting/chatroom を参照ください。
24.7. データタイプの取り扱い リンクのコピーリンクがクリップボードにコピーされました!
24.7.1. プリミティブ / 基本タイプ リンクのコピーリンクがクリップボードにコピーされました!
24.7.1.1. String 型 リンクのコピーリンクがクリップボードにコピーされました!
24.7.1.2. Number 型 リンクのコピーリンクがクリップボードにコピーされました!
Byte、 Double、 Float、 Integer、 Long、 Short の各タイプに対してサポートされます。
24.7.1.3. Boolean 型 リンクのコピーリンクがクリップボードにコピーされました!
24.7.2. JavaBeans リンクのコピーリンクがクリップボードにコピーされました!
Seam.Component.newInstance()、またはその他の場合は Seam.Remoting.createType() の新しいインスタンスを作成します。
myAction のインターフェースはそのいずれのメソッドからも直接参照されないため myWidget を含みません。 したがって MyWidget コンポーネントのインスタンスを明示的にインポートしない限りそれを渡すことができません。
<s:remote include="myAction,myWidget"/>
<s:remote include="myAction,myWidget"/>
myWidget オブジェクトが Seam.Component.newInstance("myWidget") で作成されるようになり、 myAction.doSomethingWithObject() に渡されます。
24.7.3. 日付と時刻 リンクのコピーリンクがクリップボードにコピーされました!
java.util.Date (または java.sql.Date や java.sql.Timestamp などの下位クラス) を使用します。
24.7.4. Enum リンクのコピーリンクがクリップボードにコピーされました!
paint() メソッドを red の色を使って呼び出すには、 String リテラルとしてパラメータ値を渡します。
Seam.Component.getInstance("paintAction").paint("red");
Seam.Component.getInstance("paintAction").paint("red");
24.7.5. コレクション リンクのコピーリンクがクリップボードにコピーされました!
24.7.5.1. Bag リンクのコピーリンクがクリップボードにコピーされました!
24.7.5.2. Map リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting.Map オブジェクトを作成します。
var map = new Seam.Remoting.Map();
var map = new Seam.Remoting.Map();
size()、 isEmpty()、 keySet()、 values()、 get(key)、 put(key, value)、 remove(key)、 contains(key) を提供します。 それぞれのメソッドは同じ名前の Java メソッドと同等です。 メソッドが keySet() および values() でコレクションを返すと、 そのキーまたは値オブジェクトを含む Javascript array オブジェクトが返されます。
24.8. デバッグ機能 リンクのコピーリンクがクリップボードにコピーされました!
setDebug() メソッドを実行する方法は次のとおりです。
Seam.Remoting.setDebug(true);
Seam.Remoting.setDebug(true);
components.xml で設定を行う方法は以下のとおりです。
<remoting:remoting debug="true"/>
<remoting:remoting debug="true"/>
setDebug(false) を呼び出します。 独自のメッセージをデバッグログに書き込みたい場合は、 Seam.Remoting.log(message) を呼び出します。
24.9. 例外の処理 リンクのコピーリンクがクリップボードにコピーされました!
null を指定しなければなりません。
getMessage() を公開し、 @WebRemote メソッドで送出される例外に属する例外メッセージを返します。
24.10. ロード中のメッセージ リンクのコピーリンクがクリップボードにコピーされました!
24.10.1. メッセージの変更 リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting.loadingMessage の値を設定します。
Seam.Remoting.loadingMessage = "Loading...";
Seam.Remoting.loadingMessage = "Loading...";
24.10.2. ロード中のメッセージの非表示 リンクのコピーリンクがクリップボードにコピーされました!
displayLoadingMessage() および hideLoadingMessage() の実装を何も行わない機能で上書きします。
// don't display the loading indicator
Seam.Remoting.displayLoadingMessage = function() {};
Seam.Remoting.hideLoadingMessage = function() {};
// don't display the loading indicator
Seam.Remoting.displayLoadingMessage = function() {};
Seam.Remoting.hideLoadingMessage = function() {};
24.10.3. カスタムのロード中インジケータ リンクのコピーリンクがクリップボードにコピーされました!
displayLoadingMessage() と hideLoadingMessage() の各メッセージを独自の実装で上書きしてこれを行います。
24.11. 返されるデータの制御 リンクのコピーリンクがクリップボードにコピーされました!
@WebRemote アノテーションの exclude フィールドを指定することでそのオブジェクトグラフを制約できます。このフィールドはドット (「.」) 表記を使って指定される 1 つ以上のパスを含む String 配列を受け取ります。 リモートメソッドを呼び出すと、 これらのパスと一致する結果のオブジェクトグラフにあるオブジェクトがシリアライズされる結果パケットから除外されます。
Widget クラスに基づいています。
24.11.1. 通常のフィールドの制約 リンクのコピーリンクがクリップボードにコピーされました!
Widget のインスタンスを返すけれど secret フィールドには機密情報が含まれているため公開したくない場合は、次のように制約します。
@WebRemote(exclude = {"secret"})
public Widget getWidget();
@WebRemote(exclude = {"secret"})
public Widget getWidget();
secret フィールドを参照します。
Widget 値には child フィールドがあり、 これも Widget になる点に注意してください。フィールドではなくこの child の secret 値を隠したい場合は、ドット表記を使用して結果となるオブジェクトグラフ内のこのフィールドのパスを指定することができます。
@WebRemote(exclude = {"child.secret"})
public Widget getWidget();
@WebRemote(exclude = {"child.secret"})
public Widget getWidget();
24.11.2. Map とコレクションの制約 リンクのコピーリンクがクリップボードにコピーされました!
Map またはコレクション (List、 Set、 Array など) 内にも存在することができます。コレクションはその他のフィールドと同様に扱えます。 たとえば、 Widget の widgetList フィールド内に他の Widget 一覧が含まれていて、 この一覧の Widget の secret フィールドを次のような表記で制約するとします。
@WebRemote(exclude = {"widgetList.secret"})
public Widget getWidget();
@WebRemote(exclude = {"widgetList.secret"})
public Widget getWidget();
Map のキーまたは値を制約する場合の表記は少し異なります。 Map のフィールド名の後ろに [key] を付け加えると Map のキーオブジェクト値を制約し、 [value] の場合は値オブジェクトの値を制約します。 次の例では widgetMap フィールドの値に制約された secret フィールドを持たせる方法を示しています。
@WebRemote(exclude = {"widgetMap[value].secret"})
public Widget getWidget();
@WebRemote(exclude = {"widgetMap[value].secret"})
public Widget getWidget();
24.11.3. 特定タイプのオブジェクトの制約 リンクのコピーリンクがクリップボードにコピーされました!
@WebRemote(exclude = {"[widget].secret"})
public Widget getWidget();
@WebRemote(exclude = {"[widget].secret"})
public Widget getWidget();
24.11.4. 制約同士の組み合わせ リンクのコピーリンクがクリップボードにコピーされました!
@WebRemote(exclude = {"widgetList.secret", "widgetMap[value].secret"})
public Widget getWidget();
@WebRemote(exclude = {"widgetList.secret", "widgetMap[value].secret"})
public Widget getWidget();
24.12. トランザクション的な要求 リンクのコピーリンクがクリップボードにコピーされました!
@Transactional アノテーションを @WebRemote メソッドに付与する必要があります。
24.13. JMS Messaging リンクのコピーリンクがクリップボードにコピーされました!
24.13.1. 設定 リンクのコピーリンクがクリップボードにコピーされました!
seam.properties、 web.xml または components.xml の org.jboss.seam.remoting.messaging.subscriptionRegistry.allowedTopics 配下にあるトピックを一覧表示させます。
<remoting:remoting poll-timeout="5" poll-interval="1"/>
<remoting:remoting poll-timeout="5" poll-interval="1"/>
24.13.2. JMS Topic のサブスクライブ リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting.subscribe() メソッドは 2 つのパラメータを受け取ります。1 つ目はサブスクライブする JMS Topic 名であり、2 つ目はメッセージが受け取られると呼び出すコールバック機能です。
instanceof 演算子を使ってメッセージが Seam.Remoting.TextMessage なのか Seam.Remoting.ObjectMessage かをテストすることができます。 TextMessage はその text フィールドにテキスト値を含みます (オブジェクトの getText() メソッドを呼び出してこの値をフェッチすることもできます)。 ObjectMessage はその value フィールドにオブジェクト値を含みます (getValue() メソッドを呼び出してこの値をフェッチすることもできます)。
24.13.3. トピックのサブスクライブの中止 リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting.unsubscribe() を呼び出してトピック名を渡します。
Seam.Remoting.unsubscribe("topicName");
Seam.Remoting.unsubscribe("topicName");
24.13.4. ポーリングプロセスの調整 リンクのコピーリンクがクリップボードにコピーされました!
Seam.Remoting.pollInterval は新しいメッセージに対して後続ポーリングが発生する間隔を制御します。 このパラメータは秒単位で表現され、 デフォルト設定は 10 です。
Seam.Remoting.pollTimeout も秒単位で表現されます。 サーバーへの要求がタイムアウトして空白の応答を送信するまでの新しいメッセージを待機する時間を制御します。 デフォルトは 0 秒で、 サーバーがポーリングされると配信できるメッセージがない場合は空白の応答が直ちに返されます。
pollTimeout 値を高く設定する場合は注意が必要です。メッセージを待機する必要がある各要求は、メッセージが受信されるまでまたはその要求がタイムアウトするまでサーバースレッドを使用します。こうした要求が同時に多数発生すると、 大量のサーバースレッドが使用される結果となります。
components.xml で設定することを推奨しますが、 必要に応じて JavaScript で上書きすることができます。 次の例ではよりアグレッシブなポーリングメソッドを示しています。 これらのパラメータをご使用のアプリケーションに適切な値に設定してください。
components.xml での設定
<remoting:remoting poll-timeout="5" poll-interval="1"/>
<remoting:remoting poll-timeout="5" poll-interval="1"/>
第25章 Seam と Google Web Toolkit リンクのコピーリンクがクリップボードにコピーされました!
警告
25.1. 設定 リンクのコピーリンクがクリップボードにコピーされました!
25.2. コンポーネントの準備 リンクのコピーリンクがクリップボードにコピーされました!
com.google.gwt.user.client.rpc.RemoteService を拡張するはずです。
public interface MyService extends RemoteService {
public String askIt(String question);
}
public interface MyService extends RemoteService {
public String askIt(String question);
}
AsyncCallback パラメータが追加されている点以外はまったく同じになるはずです。
public interface MyServiceAsync extends RemoteService {
public void askIt(String question, AsyncCallback callback);
}
public interface MyServiceAsync extends RemoteService {
public void askIt(String question, AsyncCallback callback);
}
MyServiceAsync) は GWT で実装されるので、絶対に直接実装しないでください。
@WebRemote アノテーションを付与する必要があります。
25.3. GWT ウィジェットを Seam コンポーネントにつなげる リンクのコピーリンクがクリップボードにコピーされました!
askServer() メソッドが呼び出され、 入力テキストの内容を渡します。 この例では、 入力値が正しい質問であるかも検証します。 askServer() メソッドは非同期クライアントスタブへの参照を取得し (getService() メソッドで返される)、 askIt() メソッドを呼び出します。 その結果はアラートウィンドウに表示されます (または呼び出しが失敗するとエラーメッセージが表示されます)。
examples/remoting/gwt ディレクトリにあります。
25.4. GWT と Ant ターゲット リンクのコピーリンクがクリップボードにコピーされました!
JAR とダウンロードした GWTが必要です。
<taskdef uri="antlib:de.samaflost.gwttasks"
resource="de/samaflost/gwttasks/antlib.xml"
classpath="./lib/gwttasks.jar"/>
<property file="build.properties"/>
<taskdef uri="antlib:de.samaflost.gwttasks"
resource="de/samaflost/gwttasks/antlib.xml"
classpath="./lib/gwttasks.jar"/>
<property file="build.properties"/>
build.properties ファイルを作成します。
gwt.home=/gwt_home_dir
gwt.home=/gwt_home_dir
webapp セクションの場合が多い)。
注記
gwt-compile で生成されたコードは絶対に編集しないでください。 編集が必要な場合には GWT ソースディレクトリ内で行ってください。
第26章 Spring Framework 統合 リンクのコピーリンクがクリップボードにコピーされました!
注記
jboss-seam-ioc ライブラリに含まれています。 これは本章に記載されているすべての Seam と Spring の統合技術に必要となる依存ライブラリです。
- Seam コンポーネントを Spring Bean にインジェクトする
- Spring Bean を Seam コンポーネントにインジェクトする
- Spring Bean を Seam コンポーネントに変換する
- Spring Bean を Seam コンテキストに配置できるようにする
- Seam コンポーネントで Spring WebApplicationContext を起動できるようにする
- Seam ベースのアプリケーションで Spring PlatformTransactionManagement の使用をサポートする
- Spring の
OpenEntityManagerInViewFilterおよびOpenSessionInViewFilterの代替として Seam 管理の使用をサポートする - Spring
TaskExecutorsで@Asynchronous呼び出しの支援をサポートする
26.1. Seam コンポーネントを Spring Bean にインジェクトする リンクのコピーリンクがクリップボードにコピーされました!
<seam:instance/> 名前空間ハンドラを使用してインジェクトします。 Seam 名前空間ハンドラを有効にするには、 Seam 名前空間をまず Spring Bean の定義ファイルに追加しなければなりません。
<seam:instance/> タグで自動的に Seam コンポーネントをプロキシできます。
OpenEntityManagerInView フィルタの代替として Seam 管理永続コンテキストを使用するためのより堅牢な方法については、「Spring での Seam 管理永続コンテキストの使用」 の項を参照してください。
26.2. Spring Bean を Seam コンポーネントにインジェクトする リンクのコピーリンクがクリップボードにコピーされました!
DelegatingVariableResolver は Spring の JavaServer Faces (JSF) との統合に役立ちます。 この VariableResolver は Bean ID を持つ EL を使って Spring Bean を JSF に対して利用できるようにします。 DelegatingVariableResolver を faces-config.xml に追加する必要があります。
@In を使って Spring Bean をインジェクトできるようになります。
@In("#{bookingService}")
private BookingService bookingService;
@In("#{bookingService}")
private BookingService bookingService;
26.3. Spring Bean を Seam コンポーネントにする リンクのコピーリンクがクリップボードにコピーされました!
<seam:component/> 名前空間ハンドラを使用すると、 あらゆる Spring Bean を Seam コンポーネントに変換することができます。 Seam コンポーネントにしたい Bean の宣言に <seam:component/> タグを追加するだけです。
<bean id="someSpringBean" class="SomeSpringBeanClass" scope="prototype"> <seam:component/> </bean>
<bean id="someSpringBean" class="SomeSpringBeanClass" scope="prototype">
<seam:component/>
</bean>
<seam:component/> は Bean 定義で与えられるクラスと名前を付けてステートレスな Seam コンポーネントを作成します。 ときおり、 FactoryBean が使用される場合など、 Spring Bean のクラス が Bean 定義に表示されるクラスとは異なることがあります。 このような場合は class を明示的に指定してください。 また、 名前付けに競合の可能性がある場合は Seam コンポーネント名も明示的に指定してください。
<seam:component/> の scope 属性を使用します。 指定される Seam スコープが STATELESS ではない場合、 Spring Bean を prototype にスコープする必要があります。既存の Spring Bean は通常基本的にステートレスな特徴を持っているので、 この属性は通常は不要です。
26.4. Seam スコープの Spring Bean リンクのコピーリンクがクリップボードにコピーされました!
<seam:configure-scopes/> を指定し、 すべての Seam スコープがカスタムスコープとして Spring Bean に利用できるようにします。 Spring Bean を特定の Seam スコープに関連付けるには、 Bean 定義の scope 属性で目的のスコープを指定します。
configure-scopes 定義内の prefix 属性を指定することによって、 スコープ名のプレフィックスを変更することができます (デフォルトのプレフィックスは seam. です)。
@In を使って参照される場合に自動的に作成されません。 インスタンスを自動作成させるには、インジェクションポイントで @In(create=true) を指定するか (特定の Bean を自動作成するため)、 configure-scopes の default-auto-create 属性を使って Seam スコープの Spring Bean がすべて自動作成されるようにします。
<seam:instance/> を使わずに他の Spring Bean にインジェクトすることができます。 ただし、スコープインピーダンスには十分注意する必要があります。 一般的には Bean 定義内で <aop:scoped-proxy/> を指定しますが、 Seam スコープの Spring Bean は <aop:scoped-proxy/> との互換性がありません。 したがって、Seam スコープ Spring Bean をシングルトンにインジェクトする場合は <seam:instance/> を使用してください。
26.5. Spring の PlatformTransactionManagement の使用 リンクのコピーリンクがクリップボードにコピーされました!
REQUIRES_NEW や NOT_SUPPORTED などの完全 Java EE トランザクション伝播のルールにも対応します。 詳細は Spring のドキュメント を参照してください。
SpringTransaction コンポーネントを以下のように有効にします。
<spring:spring-transaction
platform-transaction-manager="#{transactionManager}"/>
<spring:spring-transaction
platform-transaction-manager="#{transactionManager}"/>
spring:spring-transaction コンポーネントは同期のコールバックに Spring トランザクション同期の機能を利用します。
26.6. Spring での Seam 管理永続コンテキストの使用 リンクのコピーリンクがクリップボードにコピーされました!
EntityManager をオープンにしておくという機能があります。 これによりエンティティの分離や再併合に関連する多くの問題が解消され、LazyInitializationException の発生を軽減できます。 Spring は単一の Web 要求 (OpenEntityManagerInViewFilter) のスコープを越えて永続コンテキストを管理する方法は提供していません。
PersistenceAnnotationBeanPostProcessor、 JpaTemplate など)。
- Spring 提供のツールを使った Seam 管理永続コンテキストへの透過的なアクセス
- Web 要求以外での Seam 対話スコープ永続コンテキストへのアクセス (非同期の Quartz ジョブなど)
- Spring 管理トランザクションで Seam 管理永続コンテキストを使用する機能 (手作業による永続コンテキストのフラッシュが必要)
EntityManagerFactory ごとに 1 つのオープン EntityManager しか可能でないため、 Seam 統合は EntityManagerFactory を Seam 管理永続コンテキストでラップすることで動作します。
<bean id="seamEntityManagerFactory"
class="org.jboss.seam.ioc.spring.SeamManagedEntityManagerFactoryBean">
<property name="persistenceContextName" value="entityManager"/>
</bean>
<bean id="seamEntityManagerFactory"
class="org.jboss.seam.ioc.spring.SeamManagedEntityManagerFactoryBean">
<property name="persistenceContextName" value="entityManager"/>
</bean>
persistenceContextName は Seam 管理永続コンテキストコンポーネントの名前です。 デフォルトではこの EntityManagerFactory には Seam コンポーネント名と同等の unitName があります。この場合は entityManager です。 別の unitName を与えたい場合は次のようにして persistenceUnitName を与えることができます。
EntityManagerFactory をいずれの Spring 提供のツールでも使用することができます。この場合は、Spring の PersistenceAnnotationBeanPostProcessor を Spring で使用するのと同じように使用することができます。
<bean class="org.springframework.orm.jpa.support
.PersistenceAnnotationBeanPostProcessor"/>
<bean class="org.springframework.orm.jpa.support
.PersistenceAnnotationBeanPostProcessor"/>
EntityManagerFactory を Spring で定義するが Seam 管理永続コンテキストを使用したい場合は、 defaultPersistenceUnitName プロパティを指定してデフォルトで使用したい persistenctUnitName を PersistenceAnnotationBeanPostProcessor に指示することができます。
applicationContext.xml は次に似たようなものになります。
component.xml は次に似たようなものになります。
<persistence:managed-persistence-context name="entityManager"
auto-create="true" entity-manager-factory="#{entityManagerFactory}"/>
<persistence:managed-persistence-context name="entityManager"
auto-create="true" entity-manager-factory="#{entityManagerFactory}"/>
JpaTemplate および JpaDaoSupport は Spring ベースの永続コンテキストと通常の Seam 管理永続コンテキストではまったく同じ構成になります。
<bean id="bookingService"
class="org.jboss.seam.example.spring.BookingService">
<property name="entityManagerFactory" ref="seamEntityManagerFactory"/>
</bean>
<bean id="bookingService"
class="org.jboss.seam.example.spring.BookingService">
<property name="entityManagerFactory" ref="seamEntityManagerFactory"/>
</bean>
26.7. Spring での Seam 管理 Hibernate セッションの使用 リンクのコピーリンクがクリップボードにコピーされました!
EntityManagerFactory ごとの 1 つのオープンな EntityManager のみ Spring ツールに対して利用できるようにします。このため、 Seam はプロキシの SessionFactory を Seam 管理の Hibernate セッションコンテキストでラップすることで統合を行います。
<bean id="seamSessionFactory"
class="org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean">
<property name="sessionName" value="hibernateSession"/>
</bean>
<bean id="seamSessionFactory"
class="org.jboss.seam.ioc.spring.SeamManagedSessionFactoryBean">
<property name="sessionName" value="hibernateSession"/>
</bean>
sessionName は persistence:managed-hibernate-session コンポーネントの名前です。 これでこの SessionFactory はいずれの Spring 提供ツールでも使用することができます。 この統合は SeamManagedSessionFactory で getCurrentInstance() を呼び出している場合であれば SessionFactory.getCurrentInstance() に対する呼び出しにも対応します。
26.8. Seam コンポーネントとしての Spring Application Context リンクのコピーリンクがクリップボードにコピーされました!
ContextLoaderListener を使ってアプリケーションの Spring ApplicationContext を起動することは可能ですが制約がいくつかあります。その制約とは、Spring ApplicationContext は SeamListener の後に起動させる必要があること、また Seam ユニットと統合テストで使用するために Spring ApplicationContext を起動することは複雑になる場合があることです。
ApplicationContext を起動できる Seam コンポーネントが含まれています。 このコンポーネントを使用するには、 <spring:context-loader/> の定義を components.xml ファイルに配置します。 config-locations 属性で使用する Spring コンテキストファイルの場所を指定します。 複数の設定ファイルが必要な場合は、標準 components.xml の複数値のとおり、ネストした <spring:config-locations/> エレメントに配置することができます。
26.9. @Asynchronous への Spring TaskExecutor の使用 リンクのコピーリンクがクリップボードにコピーされました!
TaskExecutor と呼ばれる抽象を提供します。 Spring Seam 統合では @Asynchronous メソッド呼び出しを直ちに実行するために Spring の TaskExecutor を使用できます。 この機能を有効にするには SpringTaskExecutorDispatchor をインストールしてから次のように Spring Bean 定義の taskExecutor を与えます。
<spring:task-executor-dispatcher
task-executor="#{springThreadPoolTaskExecutor}"/>
<spring:task-executor-dispatcher
task-executor="#{springThreadPoolTaskExecutor}"/>
TaskExecutor は非同期イベントのスケジューリングには対応しないため、 代替となる Seam Dispatcher で処理することができます。
第27章 Hibernate Search リンクのコピーリンクがクリップボードにコピーされました!
27.1. はじめに リンクのコピーリンクがクリップボードにコピーされました!
27.2. 設定 リンクのコピーリンクがクリップボードにコピーされました!
META-INF/persistence.xml または hibernate.cfg.xml のいずれかのファイルで設定します。
注記
JAR もデプロイする必要があります。
hibernate-search.jarhibernate-commons-annotations.jarlucene-core.jar
注記
EAR 内にデプロイする場合、 application.xml の更新を忘れずに行ってください。
27.3. 使い方 リンクのコピーリンクがクリップボードにコピーされました!
Session のサブクラスとなる FullTextSession API と連携します。
FullTextSession をインジェクトします。
注記
FullTextSession が org.hibernate.Session を拡張しているため通常の Hibernate Session として使用することができます。
FullTextEntityManager は Hibernate Search が存在するところにインジェクトされます。 FullTextEntityManager は検索固有のメソッドで EntityManager を拡張します。 同様にして FullTextSession は Session を拡張します。
@PersistenceContext アノテーションを使用) は、宣言ステートメント内で FullTextEntityManager インターフェースを使うことで EntityManager インタフェースの置換はできません。 ただし、 インジェクトされる実装は FullTextEntityManager 実装になり、 ダウンキャストが可能です。
注記
Search.createFullTextSession を使用する必要がないことを覚えておいてください。
第28章 Seam の設定と Seam アプリケーションのパッケージング リンクのコピーリンクがクリップボードにコピーされました!
28.1. Seam の基本設定 リンクのコピーリンクがクリップボードにコピーされました!
28.1.1. Seam と JSF、 サーブレットコンテナとの統合 リンクのコピーリンクがクリップボードにコピーされました!
web.xml ファイルに次のエントリも必要になります。
<listener> <listener-class>org.jboss.seam.servlet.SeamListener</listener-class> </listener>
<listener>
<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>
web.xml に次を追加します。
<context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
PAGE スコープに戻るためこれが問題となる可能性があります。 JSF-RI (JSF 参照実装) でサーバー側状態保存を使用し、特定のページビューに対してページスコープの Bean にその正確な値を維持させたい場合、 コンテキストパラメータを次のように指定する必要があります。
<context-param> <param-name>com.sun.faces.serializeServerState</param-name> <param-value>true</param-value> </context-param>
<context-param>
<param-name>com.sun.faces.serializeServerState</param-name>
<param-value>true</param-value>
</context-param>
28.1.2. Facelet の使用 リンクのコピーリンクがクリップボードにコピーされました!
faces-config.xml に追加します。
<application> <view-handler>com.sun.facelets.FaceletViewHandler</view-handler> </application>
<application>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
web.xml に追加します。
<context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.xhtml</param-value> </context-param>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
28.1.3. Seam Resource Servlet リンクのコピーリンクがクリップボードにコピーされました!
web.xml に以下のエントリが必要です。
28.1.4. Seam Servlet フィルタ リンクのコピーリンクがクリップボードにコピーされました!
web.xml にマスターフィルタをインストールする必要があります。
web.xml で指定される 1 番目のフィルタで なければなりません。これでマスターフィルタが最初に実行されます。
components.xml で設定することができます。
url-pattern− フィルタされる要求を指定するのに使用します。 デフォルトは全要求です。url-patternはワイルドカードサフィックスを許可するパターンです。regex-url-pattern− フィルタされる要求を指定するのに使用します。 デフォルトは全要求です。regex-url-patternは要求パスに対する実際の正規表現の一致です。disabled− 組み込みのフィルタの無効化に使用します。
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>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:web="http://jboss.com/products/seam/web">
<web:exception-filter url-pattern="*.seam"/>
</components>
28.1.4.2. リダイレクトによる対話の伝播 リンクのコピーリンクがクリップボードにコピーされました!
components.xml の記述を以下のように調節することも可能です。
<web:redirect-filter url-pattern="*.seam"/>
<web:redirect-filter url-pattern="*.seam"/>
28.1.4.3. URL の書き換え リンクのコピーリンクがクリップボードにコピーされました!
pages.xml の設定に応じてビューの URL 書き換えを適用できます。 このフィルタはデフォルトではアクティブではありませんが、 components.xml に以下の設定を追加するとアクティブにできます。
<web:rewrite-filter view-mapping="*.seam"/>
<web:rewrite-filter view-mapping="*.seam"/>
view-mapping パラメータは web.xml ファイルにある Faces Servlet 用に定義された Servlet マッピングに一致しなければなりません。 省略すると書き換えフィルタはパターンが *.seam であるとみなします。
28.1.4.4. マルチパートフォームの送信 リンクのコピーリンクがクリップボードにコピーされました!
components.xml に以下を追加します。
<web:multipart-filter create-temp-files="true"
max-request-size="1000000" url-pattern="*.seam"/>
<web:multipart-filter create-temp-files="true"
max-request-size="1000000" url-pattern="*.seam"/>
create-temp-files−trueに設定するとアップロードされたファイルはメモリで保持されるのではなく一時ファイルに書き込まれます。 大容量ファイルのアップロードが予期されるときには考慮すべき重要な点となる場合があります。デフォルト設定は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"/>
<web:character-encoding-filter encoding="UTF-16"
override-client="true" url-pattern="*.seam"/>
encoding− 使用するエンコーディングタイプです。override-client−trueに設定すると、 要求エンコーディングはその要求がすでにエンコーディングを指定しているか否かにかかわらずencodingで指定されているものに設定されます。falseに設定すると、 クライアントが要求エンコーディングをまだ指定していない場合にのみ設定されます。 デフォルト設定はfalseです。
28.1.4.6. RichFaces リンクのコピーリンクがクリップボードにコピーされました!
web.xml に手作業で RichFaces Ajax を追加する必要はありません。
JAR 群がプロジェクトにある場合にのみインストールされます。
components.xml に追加します。 オプションは RichFaces Developer Guide に記載されているものと同じです。
<web:ajax4jsf-filter force-parser="true" enable-cache="true"
log4j-init-file="custom-log4j.xml" url-pattern="*.seam"/>
<web:ajax4jsf-filter force-parser="true" enable-cache="true"
log4j-init-file="custom-log4j.xml" url-pattern="*.seam"/>
force-parser− JSF の全ページが Richfaces の XML 構文チェッカーにより強制的に検証されるようにします。falseに設定すると、AJAX の応答のみが検証され適格な XML に変換されます。force-parserをfalseに設定するとパフォーマンスは向上しますが 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>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:web="http://jboss.com/products/seam/web">
<web:logging-filter url-pattern="*.seam"/>
</components>
28.1.4.8. カスタムなサーブレットのコンテキスト管理 リンクのコピーリンクがクリップボードにコピーされました!
FacesServlet には 絶対に 適用しないでください。 Seam は JSF 要求のコンテキスト管理にはフェーズリスナーを使用します。
components.xml で有効にする必要があります。
<web:context-filter url-pattern="/media/*"/>
<web:context-filter url-pattern="/media/*"/>
conversationId 要求パラメータで対話コンテキストの対話 ID が定義されることを期待します。必ず、要求に対話 IDを含めるようにしてください。
conversation のプロパティとして対話 ID を公開します。
28.1.4.9. カスタムフィルタの追加 リンクのコピーリンクがクリップボードにコピーされました!
web.xml で指定すると Servlet 仕様は明確な順序を提供しません)。 @Filter アノテーションを Seam コンポーネントに追加します (Seam コンポーネントは javax.servlet.Filter を実装しなければなりません) 。
@Startup アノテーションを追加すると Seam 起動時にコンポーネントが使用可能となります。 バイジェクションはここでは使用できません (@BypassInterceptors)。 フィルタは RichFaces フィルタよりチェーンの下方にします (@Filter(within="org.jboss.seam.web.ajax4jsfFilter"))。
28.1.5. EJB コンテナと Seam の統合 リンクのコピーリンクがクリップボードにコピーされました!
SeamInterceptor を Seam EJB コンポーネントに適用します。 このインターセプタはバイジェクション、 対話区分、 ビジネスプロセスのシグナルなどの操作を処理するサーバー側の組み込みインターセプタ一式に委譲します。 アプリケーション全体に渡りこれを最も容易に行うためには、次のインターセプタ設定を ejb-jar.xml に追加します。
@JndiName アノテーションを指定します。より適切な方法は、 EJB 名から JNDI 名を判断できるようパターンを指定することです。ただし、 EJB3 仕様ではグローバル JNDI をマッピングする標準的な方法は定義されていないため、 このマッピングはベンダー固有であり、命名規則により異なる可能性もあります。 このオプションは components.xml で指定します。
<core:init jndi-name="earName/#{ejbName}/local" />
<core:init jndi-name="earName/#{ejbName}/local" />
earName は Bean がデプロイされる EAR 名です。 Seam は #{ejbName} をEJB 名に置き換えるため、 最後の部分はインターフェースのタイプを表します (ローカルまたはリモート)。
EAR コンテキストの外側では (JBoss Embeddable EJB3 コンテナを使用する場合など)、 EAR がないため最初の部分は省略されて次のようなパターンになります。
<core:init jndi-name="#{ejbName}/local" />
<core:init jndi-name="#{ejbName}/local" />
EAR name/EJB name/interface タイプ) を使って自動的に EJB コンポーネントにグローバル JNDI 名を割り当てます。 次のうち値が空ではない最初の値が EJB 名となります。
ejb-jar.xml内の<ejb-name>エレメント@Statelessか@Statefulアノテーションのname属性、 または- Bean クラスの簡易名
myapp という名前で EAR にデプロイすると仮定すると、 JBoss AS で割り当てられるグローバル JNDI 名は myapp/AuthenticatorBean/local になります。 この EJB コンポーネントを authenticator という名前で Seam コンポーネントとして参照できるため、 Seam はその JNDI パターン (または @JndiName アノテーション) を使って JNDI 内で検索を行います。
web.xml で宣言する必要があります。 次はこの例で必要となるEJB 参照です。
@In アノテーションを付けて別の Seam EJB コンポーネントにインジェクトできるようにしたい場合は、この EJB 参照を 2 番目の場所となる ejb-jar.xml に定義する必要があります。 こちらの方が若干複雑です。
@In で定義されるインジェクションポイントを満たすと、 コンポーネントは JNDI 内で参照される場合にのみ見つかります。 JBoss は自動的に EJB を JNDI に登録するため、 常に Web および EJB コンテナに対して使用可能です。 他のコンテナの場合は EJB を明示的に定義する必要があります。
RegisterAction という解決済みの名前を持つ EJB があるとすると、 次の Seam インジェクションが適用されます。
@In(create = true) Authenticator authenticator;
@In(create = true) Authenticator authenticator;
ejb-jar.xml でリンクを確立する必要もあります。
web.xml で参照されたのと同じようにここで参照されます。 ここで識別することにより EJB コンテキストで参照が可能となり、 RegisterAction Bean がその参照を使用できるようになります。(@In により) 任意の Seam EJB コンポーネントの各インジェクションに対して 1 つの参照を別の Seam EJB コンポーネントに追加する必要があります。 jee5/booking サンプルでこの設定例を見ることができます。
@EJB アノテーションを付けてインジェクトすることができますが、 Seam EJB コンポーネントのインスタンスではなく EJB 参照をインジェクトすることになります。 Seam のインターセプタはいずれの メソッド呼び出し でも EJB コンポーネントに対して呼び出され、 @EJB を使用することで Seam のサーバー側のインターセプタチェーンのみを呼び出すため、 @EJB インジェクションでは動作しなくなる Seam 機能がいくつかあります (セキュリティや同時実行を行う Seam の状態管理と Seam のクライアント側インターセプタチェーンなどがこれに該当する機能です)。ステートフルセッション Bean が @EJB を使ってインジェクトされると、 必ずしもアクティブなセッションや対話にバインドするとは限らないため、 @In を使ってインジェクトを行うことをお薦めします。
java:comp/env が付くため、 JNDI パターンを次のように定義する必要があります。
<core:init jndi-name="java:comp/env/earName/#{ejbName}/local" />
<core:init jndi-name="java:comp/env/earName/#{ejbName}/local" />
Events コンポーネントで登録されるトランザクションの成功イベントを正しく処理できるような特殊な組み込みコンポーネントを使用することをお勧めします。 コンテナ管理トランザクションがいつ終了するのかを Seam に伝えるには次の行を components.xml ファイルに追加します。
<transaction:ejb-transaction/>
<transaction:ejb-transaction/>
28.1.6. 注意点 リンクのコピーリンクがクリップボードにコピーされました!
seam.properties、 META-INF/seam.properties または META-INF/components.xml ファイルを配置しておく必要があります。 Web アーカイブ (WAR) ファイルの場合は、コンポーネントがデプロイされる WEB-INF/classes ディレクトリの内側に seam.properties ファイルを配置します。
seam.properties ファイルを持つアーカイブをすべてスキャンします。 seam.properties ファイルは空でも構いませんが、 Seam がコンポーネントを認識できるようファイルを含ませなければなりません。 これは JVM (Java Virtual Machine) が持つ制約に対処する方法です。 seam.properties ファイルを持たせない場合は components.xml にすべてのコンポーネントを明示的に記載しなければならなくなります。
28.2. 代替の JPA プロバイダの使用 リンクのコピーリンクがクリップボードにコピーされました!
注記
components.xml を更新し、 汎用 PersistenceProvider が Hibernate バージョンより優先されるようにします。このファイルに次を追加するだけです。
<component name="org.jboss.seam.persistence.persistenceProvider"
class="org.jboss.seam.persistence.PersistenceProvider"
scope="stateless">
</component>
<component name="org.jboss.seam.persistence.persistenceProvider"
class="org.jboss.seam.persistence.PersistenceProvider"
scope="stateless">
</component>
PersistenceProvider の独自の実装を記述する必要があります (HibernatePersistenceProvider を起点として利用できます)。次のように Seam にこの PersistenceProvider を使うよう指示します。
<component name="org.jboss.seam.persistence.persistenceProvider"
class="org.your.package.YourPersistenceProvider">
</component>
<component name="org.jboss.seam.persistence.persistenceProvider"
class="org.your.package.YourPersistenceProvider">
</component>
persistence.xml を更新するだけです。 必要となる JAR ファイル群を使用するアプリケーションでパッケージ化するのを忘れないようにしてください。
28.3. Java EE 5 での Seam の設定 リンクのコピーリンクがクリップボードにコピーされました!
28.3.1. パッケージング リンクのコピーリンクがクリップボードにコピーされました!
EAR へのパッケージ化が終了するとアーカイブは次のような構成になります。
jboss-seam.jar を EJB モジュールとして META-INF/application.xml で宣言します。 jboss-el.jar を EAR の lib ディレクトリに配置して EAR のクラスパスに追加します。
JAR 郡を EAR の lib ディレクトリに含めます。
jsf-facelets.jar を WAR の WEB-INF/lib ディレクトリに含めます。
jboss-seam-ui.jar を WAR の WEB-INF/lib ディレクトリに含めます。 PDF や email のタグライブラリを使用する場合には、 WEB-INF/lib に jboss-seam-pdf.jar または jboss-seam-mail.jar を配置する必要もあります。
jboss-seam-debug.jar を WAR の WEB-INF/lib ディレクトリに含めます。 Seam のデバッグページが正しく動作するのは Facelets を使用するアプリケーションのみです。
28.4. J2EE での Seam の設定 リンクのコピーリンクがクリップボードにコピーされました!
UserTransaction で手作業による管理、 または Seam の @Transactional アノテーションで宣言的に管理を行うこともできます。
28.4.1. Seam での Hibernate のブートストラップ リンクのコピーリンクがクリップボードにコピーされました!
hibernate.cfg.xml ファイルから Hibernate の SessionFactory をブートストラップさせます。
<persistence:hibernate-session-factory name="hibernateSessionFactory"/>
<persistence:hibernate-session-factory name="hibernateSessionFactory"/>
Session をインジェクトにより使用可能にするには次のように managed session を設定します。
<persistence:managed-hibernate-session name="hibernateSession"
session-factory="#{hibernateSessionFactory}"/>
<persistence:managed-hibernate-session name="hibernateSession"
session-factory="#{hibernateSessionFactory}"/>
28.4.2. Seam での JPA のブートストラップ リンクのコピーリンクがクリップボードにコピーされました!
persistence.xml ファイルから JPA の EntityManagerFactory をブートストラップさせます。
<persistence:entity-manager-factory name="entityManagerFactory"/>
<persistence:entity-manager-factory name="entityManagerFactory"/>
EntityManager をインジェクトにより使用可能にするには次のように管理永続コンテキストを設定します。
<persistence:managed-persistence-context name="entityManager"
entity-manager-factory="#{entityManagerFactory}"/>
<persistence:managed-persistence-context name="entityManager"
entity-manager-factory="#{entityManagerFactory}"/>
28.4.3. パッケージング リンクのコピーリンクがクリップボードにコピーされました!
WAR としてパッケージするとアプリケーションは次のような構成になります。
28.5. JBoss Embedded のない Java SE での Seam 設定 リンクのコピーリンクがクリップボードにコピーされました!
EntityTransaction などを使用するよう指示することができます。
<transaction:entity-transaction entity-manager="#{entityManager}"/>
<transaction:entity-transaction entity-manager="#{entityManager}"/>
<transaction:hibernate-transaction session="#{session}"/>
<transaction:hibernate-transaction session="#{session}"/>
28.6. JBoss Embedded を使用した Java SE での Seam 設定 リンクのコピーリンクがクリップボードにコピーされました!
SeamTest を通じて Embedded JBoss で実行します。
28.6.1. パッケージング リンクのコピーリンクがクリップボードにコピーされました!
WAR ベースのデプロイメントは次のような構成になります。
28.7. Seam での jBPM の設定 リンクのコピーリンクがクリップボードにコピーされました!
components.xml に明示的に記載する必要があります。
jbpm.cfg.xml と hibernate.cfg.xml ファイルが含まれています。
28.7.1. パッケージング リンクのコピーリンクがクリップボードにコピーされました!
EAR のルートにパッケージされており、次のような構成となります。
28.8. JBoss ASで SFSB とセッションのタイムアウトの設定 リンクのコピーリンクがクリップボードにコピーされました!
server/default/conf/standardjboss.xml で設定されます。 これを変更するには default を希望の設定に置き換えます。
LRUStatefulContextCachePolicy キャッシュ設定で、max-bean-life の値を修正してデフォルトのステートフルセッション Bean のタイムアウトを変更します。
server/default/deployer/jboss-web.deployer/conf/web.xml で変更できます。web.xml ファイルの次のエントリはすべての Web アプリケーションのデフォルトセッションタイムアウトを制御します。
<session-config> <!-- HTTP Session timeout, in minutes --> <session-timeout>30</session-timeout> </session-config>
<session-config>
<!-- HTTP Session timeout, in minutes -->
<session-timeout>30</session-timeout>
</session-config>
web.xml に含めるだけで可能です。
28.9. Portlet での Seam の実行 リンクのコピーリンクがクリップボードにコピーされました!
警告
28.10. カスタムリソースのデプロイ リンクのコピーリンクがクリップボードにコピーされました!
/seam.properties、 /META-INF/components.xml、 または /META-INF/seam.properties を含んでいるすべての JAR をスキャンします。 たとえば、 @Name アノテーションが付与されたクラスはすべて起動時に Seam コンポーネントとして登録されます。
/META-INF/seam-deployment.properties ファイルで処理するアノテーションタイプの一覧を与えます。
# A colon-separated list of annotation types to handle org.jboss.seam.deployment.annotationTypes=com.acme.Foo:com.acme.Bar
# A colon-separated list of annotation types to handle
org.jboss.seam.deployment.annotationTypes=com.acme.Foo:com.acme.Bar
@Foo アノテーションが付くすべてのクラスを収集します。
.foo.xml 拡張子が付くファイルを処理したい場合はカスタムのデプロイメントハンドラを記述することができます。
.foo.xml が付くすべてのファイルの一覧が提供されます。
/META-INF/seam-deployment.properties でデプロイメントハンドラを Seam に登録します。
handle() は Seam のブートストラップで使用できるようかなり早くに呼び出されます。 アプリケーションによりスコープされたコンポーネントの起動中にデプロイメントハンドラに簡単にアクセスすることができます。
第29章 Seam アノテーション リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.annotations で定義されます。
29.1. コンポーネント定義のためのアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Name@Name("componentName")@Name("componentName")Copy to Clipboard Copied! Toggle word wrap Toggle overflow クラスに対して Seam コンポーネント名を定義します。 このアノテーションは Seam の全コンポーネントに必要です。@Scope@Scope(ScopeType.CONVERSATION)
@Scope(ScopeType.CONVERSATION)Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントのデフォルトコンテキストを定義します。EVENT、PAGE、CONVERSATION、SESSION、BUSINESS_PROCESS、APPLICATION、STATELESSなどのScopeTypeを列挙することで可能な値を定義します。スコープが明示的に指定されていない場合、 デフォルトはコンポーネントタイプにより異なります。 ステートレスセッション Bean の場合、 デフォルトはSTATELESSです。 エンティティ Bean およびステートフルセッション Bean なら、 デフォルトはCONVERSATIONです。JavaBeans のデフォルトはEVENTです。@Role@Role(name="roleName", scope=ScopeType.SESSION)
@Role(name="roleName", scope=ScopeType.SESSION)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Seam コンポーネントを複数のコンテキスト変数に結合できるようにします。@Nameと@Scopeのアノテーションは デフォルトロール を定義します。 各@Roleアノテーションは追加のロールを定義します。name− コンテキスト変数名です。scope− コンテキスト変数のスコープです。 スコープが明示的に指定されない場合、 デフォルトは上記のとおりコンポーネントタイプにより異なります。
@Roles@Roles({ @Role(name="user", scope=ScopeType.CONVERSATION), @Role(name="currentUser", scope=ScopeType.SESSION) })@Roles({ @Role(name="user", scope=ScopeType.CONVERSATION), @Role(name="currentUser", scope=ScopeType.SESSION) })Copy to Clipboard Copied! Toggle word wrap Toggle overflow 複数の追加ロールを指定することができます。@BypassInterceptors@BypassInterceptors
@BypassInterceptorsCopy to Clipboard Copied! Toggle word wrap Toggle overflow 特定のコンポーネントまたはコンポーネントメソッドにおける Seam インターセプタをすべて無効にします。@JndiName@JndiName("my/jndi/name")@JndiName("my/jndi/name")Copy to Clipboard Copied! Toggle word wrap Toggle overflow Seam が EJB コンポーネントの検索に使用する JNDI 名を指定します。 JNDI 名が明示的に指定されない場合、 Seam はorg.jboss.seam.core.init.jndiPatternで指定される JNDI パターンを使用します。@Conversational@Conversational
@ConversationalCopy to Clipboard Copied! Toggle word wrap Toggle overflow 対話スコープのコンポーネントが対話用であることを指定します。 つまり長期実行の対話が起こっていない限り、 そのコンポーネントのメソッドは呼び出されません。@PerNestedConversation@PerNestedConversation
@PerNestedConversationCopy to Clipboard Copied! Toggle word wrap Toggle overflow 対話スコープのコンポーネントのスコープを、 そのコンポーネントがインスタンス化された親対話だけに制限します。 そのコンポーネントのインスタンスは独自のインスタンス内で動作するネストされた子対話からは見えません。警告
これは推奨されるアプリケーション機能ではありません。 要求サイクルの特定部分にしかコンポーネントは見えないということになります。@Startup@Scope(APPLICATION) @Startup(depends="org.jboss.seam.bpm.jbpm")
@Scope(APPLICATION) @Startup(depends="org.jboss.seam.bpm.jbpm")Copy to Clipboard Copied! Toggle word wrap Toggle overflow アプリケーションスコープのコンポーネントが初期化時に直ちに開始されることを指定します。 JNDI、 データソースなど重要なインフラストラクチャをブートストラップする組み込みコンポーネントに使用されます。@Scope(SESSION) @Startup
@Scope(SESSION) @StartupCopy to Clipboard Copied! Toggle word wrap Toggle overflow セッションスコープのコンポーネントがセッション作成時に直ちに開始されることを指定します。depends− 指定されたコンポーネントがインストールされている場合は、 そのコンポーネントを先に開始しなければならないことを指定します。
@Install@Install(false)
@Install(false)Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントがデフォルトでインストールされないよう指定します (このアノテーションを指定しない場合はコンポーネントがインストールされます)。@Install(dependencies="org.jboss.seam.bpm.jbpm")
@Install(dependencies="org.jboss.seam.bpm.jbpm")Copy to Clipboard Copied! Toggle word wrap Toggle overflow 依存関係として表示されているコンポーネント群もあわせてインストールされる場合にのみ、このコンポーネントをインストールすることを指定します。@Install(genericDependencies=ManagedQueueSender.class)
@Install(genericDependencies=ManagedQueueSender.class)Copy to Clipboard Copied! Toggle word wrap Toggle overflow 特定のクラスで実装されるコンポーネントがインストールされる場合にのみ、 コンポーネントがインストールされることを指定します。必要な依存関係の名前が不定である場合に便利です。@Install(classDependencies="org.hibernate.Session")
@Install(classDependencies="org.hibernate.Session")Copy to Clipboard Copied! Toggle word wrap Toggle overflow 指定されたクラスがクラスパス内にある場合にのみ、コンポーネントをインストールするよう指定します。@Install(precedence=BUILT_IN)
@Install(precedence=BUILT_IN)Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントの優先度を指定します。 同じ名前のコンポーネントが複数存在する場合、 より高い優先度を持つコンポーネントがインストールされます。 定義される優先度の値は次の通りです (昇順)。BUILT_IN− すべての組み込み Seam コンポーネントの優先度FRAMEWORK− Seam を拡張するフレームワークのコンポーネントを使うための優先度APPLICATION− アプリケーションコンポーネントの優先度 (デフォルトの優先度)DEPLOYMENT− 特定のデプロイメントにおいてアプリケーションコンポーネントを上書きするコンポーネントを使うための優先度MOCK− テスト時に使うモックオブジェクトに対する優先度
@Synchronized@Synchronized(timeout=1000)
@Synchronized(timeout=1000)Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントが複数のクライアントによって同時にアクセスされること、 Seam が要求をシリアライズすることを指定します。 要求が特定のタイムアウト期間内にコンポーネントでロックを取得できないと例外が発生します。@ReadOnly@ReadOnly
@ReadOnlyCopy to Clipboard Copied! Toggle word wrap Toggle overflow JavaBean コンポーネントまたはコンポーネントメソッドが呼び出しの終わりで状態の複製を必要としないことを指定します。@AutoCreate@AutoCreate
@AutoCreateCopy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントが自動的に作成されるよう指定します。クライアントがcreate=trueを指定していなくても作成されます。
29.2. バイジェクション用アノテーション リンクのコピーリンクがクリップボードにコピーされました!
@In@In
@InCopy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントの属性が各コンポーネント呼び出しの開始時にコンテキスト変数からインジェクトされることを指定します。 コンテキスト変数が null の場合、 例外が送出されます。@In(required=false)
@In(required=false)Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントの属性が各コンポーネント呼び出しの開始時にコンテキスト変数からインジェクトされることを指定します。 コンテキスト変数は null でも構いません。@In(create=true)
@In(create=true)Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントの属性がコンポーネント呼び出しの開始時にコンテキスト変数からインジェクトされることを指定します。コンテキスト変数が null の場合、コンポーネントのインスタンスが Seam によって作成されます。@In(value="contextVariableName")
@In(value="contextVariableName")Copy to Clipboard Copied! Toggle word wrap Toggle overflow アノテーションを付けられたインスタンス変数名を使用せず、 コンテキスト変数名を明示的に指定します。@In(value="#{customer.addresses['shipping']}")@In(value="#{customer.addresses['shipping']}")Copy to Clipboard Copied! Toggle word wrap Toggle overflow 各コンポーネント呼び出しの開始時に JSF EL 式を評価することで、コンポーネントの属性がインジェクトされることを指定します。value− コンテキスト変数名を指定します。デフォルトはコンポーネントの属性名です。あるいは#{...}で囲まれた JSF EL 式を指定します。create− コンテキスト変数がすべてのコンテキストで未定義 (null) の場合、 Seam がコンテキスト変数と同じ名前のコンポーネントをインスタンス化するよう指定します。デフォルトはfalseです。required− コンテキスト変数がすべてのコンテキストで未定義の場合、 Seam が例外を送出するよう指定します。
@Out@Out
@OutCopy to Clipboard Copied! Toggle word wrap Toggle overflow Seam コンポーネントであるコンポーネントの属性が呼び出しの終わりでそのコンテキスト変数にアウトジェクトされることを指定します。 属性が null の場合、 例外が送出されます。@Out(required=false)
@Out(required=false)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Seam コンポーネントであるコンポーネント属性が呼び出しの終わりでそのコンテキスト変数にアウトジェクトされることを指定します。 属性は null でも構いません。@Out(scope=ScopeType.SESSION)
@Out(scope=ScopeType.SESSION)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Seam コンポーネントタイプ ではない コンポーネントの属性が呼び出しの終わりで特定スコープにアウトジェクトされることを指定します。別の方法として、明示的にスコープが指定されていない場合、@Out属性を持つコンポーネントのスコープ (またはコンポーネントがステートレスであればEVENTスコープ) が使用されます。@Out(value="contextVariableName")
@Out(value="contextVariableName")Copy to Clipboard Copied! Toggle word wrap Toggle overflow アノテーションを付けられたインスタンス変数名を使用せず、 コンテキスト変数名を明示的に指定します。value− コンテキスト変数名を指定します。デフォルトはコンポーネントの属性名です。required− アウトジェクトするときにコンポーネントの属性が null の場合、 Seam が例外を送出するよう指定します。
@In(create=true) @Out private User currentUser;
@In(create=true)
@Out private User currentUser;
@Unwrap@Unwrap
@UnwrapCopy to Clipboard Copied! Toggle word wrap Toggle overflow このアノテーションが付いている getter メソッドにより返されるオブジェクトがコンポーネントの代わりにインジェクトされることを指定します。
@Factory@Factory("processInstance") public void createProcessInstance() { ... }@Factory("processInstance") public void createProcessInstance() { ... }Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンテキスト変数に値がない場合に、 このコンポーネントのメソッドが指定コンテキスト変数の値の初期化に使用されることを指定します。 このスタイルはvoidを返すメソッドと併用します。@Factory("processInstance", scope=CONVERSATION) public ProcessInstance createProcessInstance() { ... }@Factory("processInstance", scope=CONVERSATION) public ProcessInstance createProcessInstance() { ... }Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンテキスト変数に値がない場合、 指定コンテキスト変数の値の初期化にはこのメソッドで返される値を使用することを指定します。 このスタイルは値を返すメソッドと併用します。 明示的にスコープが指定されていない場合、@Factoryメソッドを持つコンポーネントのスコープが使用されます (そのコンポーネントがステートレスではない場合EVENTコンテキストが使用されます)。value− コンテキスト変数の名前を指定します。メソッドが getter メソッドの場合、 JavaBeans のプロパティ名がデフォルトになります。scope− Seam が戻り値をバインドするスコープを指定します。値を返すファクトリメソッドの場合にのみ意味があります。autoCreate−@Inがcreate=trueを指定していない場合でも、 変数が要求されたときは常にこのファクトリメソッドが自動的に呼び出されるよう指定します。
Log をインジェクトできるようにするアノテーションです。
@Logger@Logger("categoryName")@Logger("categoryName")Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントフィールドにorg.jboss.seam.log.Logのインスタンスをインジェクトするよう指定します。 エンティティ Bean の場合、 このフィールドはstaticとして宣言されなければなりません。value− ログカテゴリの名前を指定します。デフォルトはコンポーネントのクラス名です。
@RequestParameter@RequestParameter("parameterName")@RequestParameter("parameterName")Copy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントの属性に要求パラメータ値をインジェクトするよう指定します。 基本的なタイプの対話は自動的に行われます。value− 要求パラメータの名前を指定します。デフォルトはコンポーネントの属性名です。
29.3. コンポーネントのライフサイクルメソッド用アノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Create@Create
@CreateCopy to Clipboard Copied! Toggle word wrap Toggle overflow コンポーネントのインスタンスが Seam によってインスタンス化されたときにメソッドが呼び出されるよう指定します。create メソッドは JavaBeans およびステートフルセッション Bean に対してしかサポートされません。@Destroy@Destroy
@DestroyCopy to Clipboard Copied! Toggle word wrap Toggle overflow コンテキストが終了し、 そのコンテキスト変数が破棄されるときにメソッドが呼び出されることを指定します。destroy メソッドは JavaBeans およびステートフルセッション Bean に対してしかサポートされません。Destroy メソッドはクリーンアップにのみ使用するようにしてください。 Seam は destroy メソッドから伝播する例外はすべてキャッチしてログを出力し、捨ててしまいます。@Observer@Observer("somethingChanged")@Observer("somethingChanged")Copy to Clipboard Copied! Toggle word wrap Toggle overflow 指定されたタイプのコンポーネント駆動イベントが発生すると、 このメソッドが呼び出されるよう指定します。@Observer(value="somethingChanged",create=false)
@Observer(value="somethingChanged",create=false)Copy to Clipboard Copied! Toggle word wrap Toggle overflow 指定したタイプのイベントが発生したときにそのメソッドを呼び出すこと、 ただしインスタンスが存在しない場合はそのインスタンスは作成されないことを指定します。 インスタンスが存在せず、 create がfalseに設定されている場合はイベントは監視されません。 create のデフォルト値はtrueです。
29.4. コンテキスト境界用アノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Begin を付けたメソッドを呼び出すことで、その対話を 長期実行の対話 に「昇格」させなければなりません。
@Begin@Begin
@BeginCopy to Clipboard Copied! Toggle word wrap Toggle overflow このメソッドが例外を送出することなく null 以外の結果を返す場合、長期対話の対話が開始することを指定します。@Begin(join=true)
@Begin(join=true)Copy to Clipboard Copied! Toggle word wrap Toggle overflow 長期実行の対話がすでに開始されている場合、 対話コンテキストが伝播されることを指定します。@Begin(nested=true)
@Begin(nested=true)Copy to Clipboard Copied! Toggle word wrap Toggle overflow 長期実行の対話がすでに開始されている場合、 新たに ネストされた 対話コンテキストが開始することを指定します。 次の@Endが出現したときにこのネストされた対話が終了し、 外側の対話が再開します。 外側の同じ対話内でネストされた複数の対話を同時に存在させることが可能です。@Begin(pageflow="process definition name")
@Begin(pageflow="process definition name")Copy to Clipboard Copied! Toggle word wrap Toggle overflow この対話のためのページフローを定義する jBPM プロセス定義の名前を指定します。@Begin(flushMode=FlushModeType.MANUAL)
@Begin(flushMode=FlushModeType.MANUAL)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Seam 管理永続コンテキストのフラッシュモードを指定します。flushMode=FlushModeType.MANUALは アトミックな対話 の使用に対応します。 この場合、flush ()(通常、 対話終了時に呼び出される) への明示的な呼び出しが起きるまで、 すべての書き込み操作は対話コンテキスト内の待ち行列に入れられます。join− 長期実行の対話が既に始まっている場合にその動作を確定します。trueならば、 コンテキストは伝播されます。falseの場合は例外が送出されます。 デフォルトはfalseです。nested=trueが指定されている場合はこの設定は無視されます。nested− 長期実行の対話が既に開始されている場合はネストした対話が開始されることを指定します。flushMode− この対話で作成される Seam 管理の Hibernate セッションまたは JPA 永続コンテキストのフラッシュモードを設定します。pageflow−org.jboss.seam.bpm.jbpm.pageflowDefinitionsによってデプロイされる jBPM プロセス定義の名前です。
@End@End
@EndCopy to Clipboard Copied! Toggle word wrap Toggle overflow このメソッドが例外を送出することなく null 以外の結果を返す場合、長期実行の対話が終了することを指定します。beforeRedirect− デフォルトでは、 リダイレクトが発生するまでこの対話は実際には破棄されません。beforeRedirect=trueを設定することで、 現在の要求の最後に対話が破棄され、 リダイレクトは新しい一時的な対話コンテキストで処理されるよう指定します。root− デフォルトでは、 ネストした対話が終了すると対話のスタックを単純にポップして外側の対話を再開します。root=trueを設定することで、 ルートの対話が破棄され、 結果的に対話スタック全体が破棄されるよう指定します。 対話がネストしていなければ現在の対話が破棄します。
@StartTask@StartTask
@StartTaskCopy to Clipboard Copied! Toggle word wrap Toggle overflow jBPM タスクを開始します。 このメソッドが例外を送出することなく null 以外の結果を返すと長期実行の対話を開始することを指定します。 この対話は指定の要求パラメータ中で指定される jBPM タスクと関連しています。 この対話のコンテキスト内で、 タスクインスタンスのビジネスプロセスインスタンスに対して、 ビジネスプロセスコンテキストも定義されます。- jBPM
TaskInstanceはtaskInstance要求コンテキスト変数で利用可能です。 jBPMProcessInstanceはprocessInstance要求コンテキスト変数で利用可能です。 これらのオブジェクトは@Inでインジェクションが可能です。 taskIdParameter− タスク ID を保持する要求パラメータの名前です。 デフォルトは"taskId"です。これは SeamtaskListJSF コンポーネントによりデフォルトとしても使用されます。flushMode− この対話で作成される Seam 管理の Hibernate セッションまたは JPA 永続コンテキストのフラッシュモードを設定します。
@BeginTask@BeginTask
@BeginTaskCopy to Clipboard Copied! Toggle word wrap Toggle overflow 完了していない jBPM タスクの処理を再開します。 このメソッドが例外を送出せず null 以外の結果を返すと長期実行の対話が開始することを指定します。 この対話は指定の要求パラメータ中で指定される jBPM タスクと関連しています。 この対話のコンテキスト内で、 タスクインスタンスのビジネスプロセスインスタンスに対して、 ビジネスプロセスコンテキストも定義されます。- jBPM
org.jbpm.taskmgmt.exe.TaskInstanceはtaskInstanceの要求コンテキスト変数で利用可能です。 jBPMorg.jbpm.graph.exe.ProcessInstanceは、processInstanceの要求コンテキスト変数で利用可能です。 taskIdParameter− タスクの ID を保持する要求パラメータの名前です。 デフォルトは"taskId"です。 これは SeamtaskListJSF コンポーネントによりデフォルトとしても使用されます。flushMode− この対話で作成される Seam 管理の Hibernate セッションまたは JPA 永続コンテキストのフラッシュモードを設定します。
@EndTask@EndTask
@EndTaskCopy to Clipboard Copied! Toggle word wrap Toggle overflow jBPM タスクを終了します。 このメソッドが null 以外の結果を返すと長期実行の対話は終了し、 現在のタスクが完了することを指定します。 jBPM 遷移を引き起こします。 アプリケーションがtransitionと呼ばれる組み込みコンポーネントのTransition.setName()を呼んでいない限り、 引き起こされる実際の遷移はデフォルトの遷移になります。@EndTask(transition="transitionName")
@EndTask(transition="transitionName")Copy to Clipboard Copied! Toggle word wrap Toggle overflow 指定された jBPM 遷移を引き起こします。transition− タスクの終了時に引き起こされる jBPM 遷移の名前です。デフォルト設定でデフォルトの遷移となっています。beforeRedirect− デフォルトでは、 リダイレクトが発生するまでこの対話は実際には破棄されません。beforeRedirect=trueを設定することで、 現在の要求の最後に対話が破棄され、 リダイレクトは新しい一時的な対話コンテキストで処理されるよう指定します。
@CreateProcess@CreateProcess(definition="process definition name")
@CreateProcess(definition="process definition name")Copy to Clipboard Copied! Toggle word wrap Toggle overflow メソッドが例外を送出せずに null 以外の結果を返すとき、 新しい jBPM プロセスインスタンスを作成します。ProcessInstanceオブジェクトはprocessInstanceというコンテキスト変数で使用できます。definition−org.jboss.seam.bpm.jbpm.processDefinitionsによってデプロイされる jBPM プロセス定義の名前です。
@ResumeProcess@ResumeProcess(processIdParameter="processId")
@ResumeProcess(processIdParameter="processId")Copy to Clipboard Copied! Toggle word wrap Toggle overflow メソッドが例外を送出せずに null 以外の結果を返すとき、 既存の jBPM プロセスインスタンスのスコープに再度入ります。ProcessInstanceオブジェクトはprocessInstanceというコンテキスト変数で使用できます。processIdParameter− プロセス ID を保持する要求パラメータの名前です。 デフォルトは"processId"です。
@Transition@Transition("cancel")@Transition("cancel")Copy to Clipboard Copied! Toggle word wrap Toggle overflow メソッドが null 以外の結果を返すときは常に現在の jBPM プロセスインスタンス内で遷移にシグナルを送るように、メソッドをマークします。
29.5. J2EE 環境で Seam JavaBean コンポーネントを使用するためのアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Transactional@Transactional
@TransactionalCopy to Clipboard Copied! Toggle word wrap Toggle overflow JavaBean コンポーネントにセッション Bean コンポーネントのデフォルト動作と同じようなトランザクション動作を持たせることを指定します。 例えば、 メソッド呼び出しはトランザクション内で起こるべきであり、 メソッドが呼び出されたときにトランザクションが存在しない場合は、 トランザクションがそのメソッドのためだけに開始されます。 このアノテーションはクラスレベルでもメソッドレベルでも適用可能です。注記
EJB3 コンポーネントではこのアノテーションではなく、@TransactionAttributeを代わりに使用してください。@ApplicationException@ApplicationException
@ApplicationExceptionCopy to Clipboard Copied! Toggle word wrap Toggle overflow アプリケーション例外でありクライアントに直接報告すべきであることを示す例外に適用されます (ラップされていないということです)。 Java EE 5 より前の環境で使用する場合はjavax.ejb.ApplicationExceptionとまったく同様に動作します。注記
EJB3 コンポーネントではこのアノテーションではなく、@javax.ejb.ApplicationExceptionを代わりに使用してください。rollback− デフォルトではfalseです。trueの場合この例外はトランザクションを rollback only に設定します。end− デフォルトではfalseです。trueの場合この例外は現在の長期実行の対話を終了します。
@Interceptors@Interceptors({DVDInterceptor, CDInterceptor})@Interceptors({DVDInterceptor, CDInterceptor})Copy to Clipboard Copied! Toggle word wrap Toggle overflow クラスまたはメソッドのインターセプタの順序一覧を宣言します。 Java EE 5 より前の環境で使用する場合はjavax.interceptors.Interceptorsとまったく同様に動作します。これはメタアノテーションとしての使用のみに限定してください。注記
EJB3 コンポーネントではこのアノテーションではなく、@javax.interceptor.Interceptorsを代わりに使用してください。
29.6. 例外用のアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Redirect@Redirect(viewId="error.jsp")
@Redirect(viewId="error.jsp")Copy to Clipboard Copied! Toggle word wrap Toggle overflow このアノテーションが付いている例外によりブラウザが指定されたビュー ID にリダイレクトされることを指定します。viewId− リダイレクト先となる JSF ビュー ID を指定します。ここで EL を利用することができます。message− 表示するメッセージです。 デフォルトはその例外メッセージです。end− 長期実行の対話が終了するよう指定します。 デフォルトはfalseです。
@HttpError@HttpError(errorCode=404)
@HttpError(errorCode=404)Copy to Clipboard Copied! Toggle word wrap Toggle overflow このアノテーションが付いている例外により HTTP エラーが送信されます。errorCode− HTTP エラーコードです。 デフォルトは500です。message− HTTP エラーで送信されるメッセージです。 デフォルトはその例外メッセージです。end− 長期実行の対話が終了するよう指定します。 デフォルトはfalseです。
29.7. Seam Remoting 用のアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@WebRemote@WebRemote(exclude="path.to.exclude")
@WebRemote(exclude="path.to.exclude")Copy to Clipboard Copied! Toggle word wrap Toggle overflow クライアント側の JavaScript からアノテーション付きメソッドの呼び出しが可能であることを示します。excludeプロパティはオプションで、 これを使用すると結果のオブジェクトグラフからオブジェクトを除外することができます (詳細は 24章リモーティング の章を参照してください)。
29.8. Seam インターセプタ用のアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Interceptor@Interceptor(stateless=true)
@Interceptor(stateless=true)Copy to Clipboard Copied! Toggle word wrap Toggle overflow このインターセプタはステートレスであることを指定するので、 Seam は複製処理を最適化できます。@Interceptor(type=CLIENT)
@Interceptor(type=CLIENT)Copy to Clipboard Copied! Toggle word wrap Toggle overflow このインターセプタは EJB コンテナより先に呼ばれる「クライアント側」インターセプタであることを指定します。@Interceptor(around={SomeInterceptor.class, OtherInterceptor.class})@Interceptor(around={SomeInterceptor.class, OtherInterceptor.class})Copy to Clipboard Copied! Toggle word wrap Toggle overflow このインターセプタは特定のインターセプタよりスタック内でより高い位置に配置されることを指定します。@Interceptor(within={SomeInterceptor.class, OtherInterceptor.class})@Interceptor(within={SomeInterceptor.class, OtherInterceptor.class})Copy to Clipboard Copied! Toggle word wrap Toggle overflow このインターセプタは特定のインターセプタよりスタック内でより深い位置に配置されることを指定します。
29.9. 非同期用のアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Asynchronous public void scheduleAlert(Alert alert,
@Expiration Date date) {
...
}
@Asynchronous public void scheduleAlert(Alert alert,
@Expiration Date date) {
...
}
@Asynchronous public Timer scheduleAlerts(Alert alert,
@Expiration Date date,
@IntervalDuration long interval) {
...
}
@Asynchronous public Timer scheduleAlerts(Alert alert,
@Expiration Date date,
@IntervalDuration long interval) {
...
}
@Asynchronous@Asynchronous
@AsynchronousCopy to Clipboard Copied! Toggle word wrap Toggle overflow メソッド呼び出しが非同期で処理されることを指定します。@Duration@Duration
@DurationCopy to Clipboard Copied! Toggle word wrap Toggle overflow 非同期呼び出しが処理されるまでの期間に関連するその呼び出しのパラメータを指定します (または反復呼び出しの場合は初めての処理が行われるまで) 。@Expiration@Expiration
@ExpirationCopy to Clipboard Copied! Toggle word wrap Toggle overflow 非同期呼び出しが処理される (または反復呼び出しの場合は初めての処理が行われる) 日付と時刻に関連するその呼び出しのパラメータを指定します。@IntervalDuration@IntervalDuration
@IntervalDurationCopy to Clipboard Copied! Toggle word wrap Toggle overflow 非同期のメソッド呼び出しが反復することを指定します。 関連付けられたパラメータはその反復間隔の長さを定義します。
29.10. JSF と使用するアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Converter- Seam コンポーネントが JSF コンバータとして動作できるようにします。アノテーションを付けられたクラスは Seam コンポーネントでなければいけません。また
javax.faces.convert.Converterを実装しなければなりません。id− JSF コンバータの ID です。 デフォルトはコンポーネント名です。forClass− 指定されると、 このコンポーネントをある型のデフォルトコンバータとして登録します。
@Validator- Seam コンポーネントが JSF バリデータとして動作できるようにします。アノテーションを付けられたクラスは Seam コンポーネントでなければいけません。また
javax.faces.validator.Validatorを実装しなければなりません。id− JSF バリデータの ID です。 デフォルトはコンポーネント名です。
29.10.1. dataTable と使用するアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@DataModel@DataModel("variableName")@DataModel("variableName")Copy to Clipboard Copied! Toggle word wrap Toggle overflow List、Map、SetまたはObject[]型のプロパティを JSFDataModelとして所有しているコンポーネントのスコープ (所有しているコンポーネントがSTATELESSの場合はEVENTスコープ) へアウトジェクトします 。Mapの場合、DataModelの各行はMap.Entryです。value− 対話コンテキスト変数の名前です。 デフォルトは属性の名前です。scope−scope=ScopeType.PAGEが明示的に指定されると、DataModelはPAGEコンテキストに保持されるようになります。
@DataModelSelection@DataModelSelection
@DataModelSelectionCopy to Clipboard Copied! Toggle word wrap Toggle overflow JSFDataModelから選択された値をインジェクトします (これは基礎となるコレクションのエレメントまたはマップ値です)。 コンポーネントにひとつしか@DataModel属性が定義されていなければ、 そのDataModelから選択された値がインジェクトされます。これ以外は、 各@DataModelのコンポーネント名を各@DataModelSelectionの value 属性に指定しなければなりません。関連付けられた@DataModelにPAGEスコープが指定されると、 DataModel Selection がインジェクトされるのに加えて関連付けられた DataModel もインジェクトされます。このとき、@DataModelのアノテーションが付いたプロパティが getter メソッドである場合、 プロパティの setter メソッドも含まれている Seam Component を含む Business API の一部でなければなりません。value− 対話コンテキスト変数の名前です。 コンポーネントに 1 つの@DataModelしかない場合は不要です。
@DataModelSelectionIndex@DataModelSelectionIndex
@DataModelSelectionIndexCopy to Clipboard Copied! Toggle word wrap Toggle overflow JSFDataModelの選択インデックスをコンポーネントの属性として公開します (これは基礎となるコレクションの行番号またはマップキーです)。 1 コンポーネントにひとつしか@DataModel属性が定義されていなければ、 そのDataModelから選択された値がインジェクトされます。 これ以外は、 各@DataModelのコンポーネント名を各@DataModelSelectionIndexの value 属性に指定する必要があります。value− 対話コンテキスト変数の名前です。 コンポーネントに 1 つの@DataModelしかない場合は不要です。
29.11. データバインディング用のメタアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@DataModel や @DataModelSelection と同様の機能の実装を可能にします。
@DataBinderClass@DataBinderClass(DataModelBinder.class)
@DataBinderClass(DataModelBinder.class)Copy to Clipboard Copied! Toggle word wrap Toggle overflow アノテーションがデータバインディングのアノテーションであることを指定します。@DataSelectorClass@DataSelectorClass(DataModelSelector.class)
@DataSelectorClass(DataModelSelector.class)Copy to Clipboard Copied! Toggle word wrap Toggle overflow アノテーションがデータ選択のアノテーションであることを指定します。
29.12. パッケージング用のアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Namespace@Namespace(value="http://jboss.com/products/seam/example/seampay")
@Namespace(value="http://jboss.com/products/seam/example/seampay")Copy to Clipboard Copied! Toggle word wrap Toggle overflow 現在のパッケージにあるコンポーネントが特定の名前空間に関連付けられることを指定します。 宣言された名前空間はcomponents.xmlファイル内で XML 名前空間として使用することでアプリケーションの設定を簡略化することができます。@Namespace(value="http://jboss.com/products/seam/core", prefix="org.jboss.seam.core")@Namespace(value="http://jboss.com/products/seam/core", prefix="org.jboss.seam.core")Copy to Clipboard Copied! Toggle word wrap Toggle overflow 名前空間を特定のパッケージに関連付けるよう指定します。さらに、あるコンポーネントの名前のプレフィックスが XML ファイルで指定されたコンポーネント名に適用されることを指定します。 たとえば、 この名前空間に関連付けられるinitという XML 要素は実際にはorg.jboss.seam.core.initというコンポーネントを参照するように解釈されます。
29.13. Servlet コンテナと統合するためのアノテーション リンクのコピーリンクがクリップボードにコピーされました!
@Filterjavax.servlet.Filterを実装している Seam コンポーネントにアノテーションを付与するために使用する場合、 Seam のマスターフィルタで実行されるサーブレットフィルタとしてそのコンポーネントを指定します。@Filter(around={"seamComponent", "otherSeamComponent"})@Filter(around={"seamComponent", "otherSeamComponent"})Copy to Clipboard Copied! Toggle word wrap Toggle overflow このフィルタは特定のフィルタよりスタック内でより高い位置に配置されることを指定します。@Filter(within={"seamComponent", "otherSeamComponent"})@Filter(within={"seamComponent", "otherSeamComponent"})Copy to Clipboard Copied! Toggle word wrap Toggle overflow このフィルタは特定のフィルタよりスタック内でより深い位置に配置されることを指定します。
第30章 組み込み Seam コンポーネント リンクのコピーリンクがクリップボードにコピーされました!
components.xml ファイルに記載されていなくても自動的に作成されます。ただし、デフォルトのプロパティを上書き、または特定タイプのコンポーネントを複数指定する必要がある場合は components.xml を使用します。
@Name を使って適切な組み込みコンポーネントにちなみ独自のクラスに名前を付けるだけでいずれの組み込みコンポーネントも独自の実装に置き換えることができます。
30.1. コンテキストインジェクションのコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
@In private Context sessionContext;
@In private Context sessionContext;
org.jboss.seam.core.contexts- Seam Context オブジェクトへのアクセスを提供するコンポーネントです。 たとえば、
org.jboss.seam.core.contexts.sessionContext['user']など。 org.jboss.seam.faces.facesContextFacesContextコンテキストオブジェクトのマネージャコンポーネントです (正確には Seam コンテキストではありません)。
30.2. JMS 関連のコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.faces.dateConverter- タイプ
java.util.Dateのプロパティ用のデフォルト JSF コンバータを提供します。このコンバータは自動的に JSF に登録されるため、 開発者は入力フィールドやページパラメータに DateTimeConverter を指定する必要がありません。 デフォルトではタイプは日付 (時間や日時とは対照的に) と仮定して、 ユーザーのLocaleに調整された短い入力スタイルを使用します。Locale.USの場合、 入力パターンはmm/dd/yyです。 ただし、 Y2K に準拠するため、 年は 2 桁から 4 桁に変更されます (mm/dd/yyyy)。コンポーネントを再設定することで入力パターンをグローバルに上書きすることができます。 このクラスに関する JavaServer Faces ドキュメントでサンプルを参照してください。 org.jboss.seam.faces.facesMessages- Faces がブラウザリダイレクト全体に成功のメッセージを伝播できるようにします。
add(FacesMessage facesMessage)− Faces メッセージを追加します。 現在の対話内で発生する次のレスポンス出力フェーズで表示されます。add(String messageTemplate)− Faces メッセージを追加します。EL 式を含むことができる特定のメッセージテンプレートからレンダリングされます。add(Severity severity, String messageTemplate)− Faces メッセージを追加します。EL 式を含むことができる特定のメッセージテンプレートからレンダリングされます。addFromResourceBundle(String key)− Faces メッセージを追加します。EL 式を含むことができる Seam リソースバンドルで定義されたメッセージテンプレートからレンダリングされます。addFromResourceBundle(Severity severity, String key)− Faces メッセージを追加します。EL 式を含むことができる Seam リソースバンドルで定義されたメッセージテンプレートからレンダリングされます。clear()− 全メッセージを消去します。
org.jboss.seam.faces.redirect- パラメータ付きでリダイレクトを行う場合に便利な API です。 特にブックマーク可能な検索結果画面などに役立ちます。
redirect.viewId− リダイレクト先となる JSF ビュー ID です。redirect.conversationPropagationEnabled− 対話をリダイレクト全体に伝播させるかどうか決定します。redirect.parameters− 値への要求パラメータ名のマップで、リダイレクト要求に渡されます。execute()− リダイレクトを直ちに実行します。captureCurrentRequest()− 現在の GET 要求 (対話コンテキスト内) の要求パラメータとビュー ID を格納します。execute()の呼び出しで後ほど使用されます。
org.jboss.seam.faces.httpError- HTTP エラーを送信する場合に便利な API です。
org.jboss.seam.ui.renderStampStore- レンダリングスタンプのコレクションを管理するコンポーネントです。 レンダリングスタンプはレンダリングされたフォームがサブミットされたかどうかを示します。 特に JSF のクライアント側の状態保存のメソッドと併用すると便利です。 フォームのステータス (ポストされたまたはされていない) はクライアントではなくサーバーによって制御されているためです。クライアント側の状態保存はセッションからこのチェックのバインディングを外すためによく使用されます。 これを行うにはそのアプリケーション (アプリケーションが実行中は有効) またはデータベース (サーバーが再起動されても有効) 内にレンダリングスタンプを保存できる実装が必要となります。
maxSize— ストアに保持可能なスタンプの最大数です。 デフォルトは100です。
javax.faces.context.FacesContext クラスが使用可能な場合にインストールされます。
30.3. ユーティリティコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.core.events@Observerのメソッドまたはcomponents.xml内のメソッドバインディングで監視できるイベントを引き起こす API です。raiseEvent(String type)− 特定タイプのイベントを発生させてすべての監視者に配信します。raiseAsynchronousEvent(String type)− EJB3 タイマーサービスで非同期に処理されるイベントを発生させます。raiseTimedEvent(String type, ....)− EJB3 タイマーサービスで非同期に処理されるイベントをスケジュールします。addListener(String type, String methodBinding)− 特定イベントタイプの監視者を追加します。
org.jboss.seam.core.interpolator- 文字列内に JFS EL 式の値を挿入するための API です。
interpolate(String template)−#{...}形式の JSF EL 式のテンプレートをスキャンしてその評価値と置換します。
org.jboss.seam.core.expressions- 値とメソッドのバインティングを作成するための API です。
createValueBinding(String expression)− 値バインディングのオブジェクトを作成します。createMethodBinding(String expression)− メソッドバインディングのオブジェクトを作成します。
org.jboss.seam.core.pojoCache- JBoss Cache
PojoCacheインスタンスのマネージャコンポーネントです。pojoCache.cfgResourceName− 設定ファイル名です。 デフォルトではtreecache.xmlに設定されます。
30.4. 国際化とテーマのコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.core.locale- Seam ロケールです。
org.jboss.seam.international.timezone- Seam のタイムゾーンです。 タイムゾーンはセッションスコープです。
org.jboss.seam.core.resourceBundle- Seam リソースバンドルです。 リソースバンドルはステートレスです。 Seam リソースバンドルは Java リソースバンドル一覧内にあるキーに深さ優先検索を行います。
org.jboss.seam.core.resourceLoader- リソースローダーはアプリケーションリソースおよびリソースバンドルへのアクセスを提供します。
resourceLoader.bundleNames− Seam リソースバンドルを使用する場合に検索する Java リソースバンドルの名前です。 デフォルトはmessagesです。
org.jboss.seam.international.localeSelector- 設定時間またはランタイム時のユーザーのいずれかでロケール選択をサポートします。
select()− 指定されたロケールを選択します。localeSelector.locale− 実際のjava.util.Localeです。localeSelector.localeString− ロケールの文字列表現です。localeSelector.language− 指定されたロケールの言語です。localeSelector.country− 指定されたロケールの国です。localeSelector.variant− 指定されたロケールのバリアントです。localeSelector.supportedLocales−jsf-config.xmlに記載のサポートロケールを表しているSelectItem一覧です。localeSelector.cookieEnabled− ロケール選択がクッキーで永続化されることを指定します。
org.jboss.seam.international.timezoneSelector- 設定時間またはランタイム時のユーザーのいずれかでタイムゾーン選択をサポートします。
select()− 指定されたロケールを選択します。timezoneSelector.timezone− 実際のjava.util.TimeZoneです。timezoneSelector.timeZoneId− タイムゾーンの文字列表現です。timezoneSelector.cookieEnabled− タイムゾーン選択がクッキーによって永続化されることを指定します。
org.jboss.seam.international.messages- Seam リソースバンドル内で定義されるメッセージテンプレートからレンダリングした国際化メッセージを含んでいるマップです。
org.jboss.seam.theme.themeSelector- 設定時間またはランタイム時のユーザーのいずれかでテーマ選択をサポートします。
select()− 指定されたテーマを選択します。theme.availableThemes− 定義されたテーマの一覧です。themeSelector.theme− 選択されたテーマです。themeSelector.themes− 定義されたテーマを表しているSelectItemの一覧です。themeSelector.cookieEnabled− テーマ選択がクッキーで永続化されることを指定します。
org.jboss.seam.theme.theme- テーマエントリを含んでいるマップです。
30.5. 対話を制御するためのコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.core.conversation- アプリケーション内から現在の Seam 対話の属性を制御するための API です。
getId()− 現在の対話 ID を返します。isNested()− 現在の対話がネストされている対話かどうかを指定します。isLongRunning()− 現在の対話が長期実行の対話であるかどうかを指定します。getId()− 現在の対話 ID を返します。getParentId()− 親対話の対話 ID を返します。getRootId()− ルート対話の対話 ID を返します。setTimeout(int timeout)− 現在の対話のタイムアウトを設定します。setViewId(String outcome)− 対話スイッチャー、 対話リストまたはブレッドクラムから現在の対話に切り替えて戻した場合に使用する ビュー ID を設定します。setDescription(String description)− 対話スイッチャー、 対話リストまたはブレッドクラムで表示される現在の対話の詳細を設定します。redirect()− この対話用に明確に定義された最後のビュー ID にリダイレクトします。 ログイン試行後に使うと便利です。leave()− 実際には対話を終了せずにこの対話のスコープを終了します。begin()− 長期実行の対話を開始します (@Beginと同等)。beginPageflow(String pageflowName)− ページフローを付けて長期実行の対話を開始します (@Begin(pageflow="...")と同等)。end()− 長期実行の対話を終了します (@Endと同等)。pop()− 対話スタックをポップして親対話に戻ります。root()− 対話スタックのルート対話に戻ります。changeFlushMode(FlushModeType flushMode)− 対話のフラッシュモードを変更します。
org.jboss.seam.core.conversationList- 対話一覧のマネージャコンポーネントです。
org.jboss.seam.core.conversationStack- 対話スタックのマネージャコンポーネントです (ブレッドクラム)。
org.jboss.seam.faces.switcher- 対話スイッチャーです。
30.6. jBPM 関連のコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.pageflow.pageflow- Seam ページフロー制御用の API です。
isInProcess()− 現在プロセス中のページフローがある場合にはtrueを返します。getProcessInstance()− 現在のページフローの jBPMProcessInstanceを返します。begin(String pageflowName)− 現在の対話のコンテキスト内でページフローを開始します。reposition(String nodeName)− 現在のページフローを特定ノードに再配置します。
org.jboss.seam.bpm.actor- 現在のセッションに関連付けられた jBPM actor の属性をアプリケーション内から制御する API です。
setId(String actorId)− 現在のユーザーの jBPM actor ID を設定します。getGroupActorIds()− 現在のユーザーグループ群用の jBPM actor ID が追加されるSetを返します。
org.jboss.seam.bpm.transition- 現在のタスクの jBPM 遷移をアプリケーション内から制御する API です。
setName(String transitionName)− 現在のタスクが@EndTaskで終了される場合に使用する jBPM 遷移名を設定します。
org.jboss.seam.bpm.businessProcess- 対話とビジネスプロセス間の関連性をプログラム制御するための API です。
businessProcess.taskId− 現在の対話に関連付けられたタスクの ID です。businessProcess.processId− 現在の対話に関連付けられたプロセスの ID です。businessProcess.hasCurrentTask()− タスクインスタンスを現在の対話に関連付けるかどうかを指定します。businessProcess.hasCurrentProcess()− プロセスインスタンスを現在の対話に関連付けるかどうかを指定します。createProcess(String name)− 名前付きプロセスの定義のインスタンスを作成し現在の対話に関連付けます。startTask()− 現在の対話に関連付けられたタスクを開始します。endTask(String transitionName)− 現在の対話に関連付けられたタスクを終了します。resumeTask(Long id)− 特定の ID を持つタスクを現在の対話に関連付けます。resumeProcess(Long id)− 特定の ID を持つプロセスを現在の対話に関連付けます。transition(String transitionName)− 遷移を引き起こします。
org.jboss.seam.bpm.taskInstance- jBPM
TaskInstanceのマネージャコンポーネントです。 org.jboss.seam.bpm.processInstance- jBPM
ProcessInstanceのマネージャコンポーネントです。 org.jboss.seam.bpm.jbpmContext- イベントスコープ
JbpmContextのマネージャコンポーネントです。 org.jboss.seam.bpm.taskInstanceList- jBPM タスクリストのマネージャコンポーネントです。
org.jboss.seam.bpm.pooledTaskInstanceList- jBPM プールされたタスクリストのマネージャコンポーネントです。
org.jboss.seam.bpm.taskInstanceListForType- jBPM タスクリスト集のマネージャコンポーネントです。
org.jboss.seam.bpm.pooledTask- プールされたタスク割り当てのアクションハンドラです。
org.jboss.seam.bpm.processInstanceFinder- プロセスインスタンスのタスクリストのマネージャコンポーネントです。
org.jboss.seam.bpm.processInstanceList- プロセスインスタンスのタスクリストです。
org.jboss.seam.bpm.jbpm コンポーネントがインストールされると常にこれらの全コンポーネントがインストールされます。
30.7. セキュリティ関連のコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.web.userPrincipal- 現在のユーザー
Principalのマネージャコンポーネントです。 org.jboss.seam.web.isUserInRole- 現在の principal に使用可能なロールに応じて JSF ページがコントロールのレンダリングを選択できるようにします。例えば
<h:commandButton value="edit" rendered="#{isUserInRole['admin']}"/>です。
30.8. JMS 関連のコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
TopicPublisher および QueueSender との併用を目的としています (下記参照)。
org.jboss.seam.jms.queueSession- JMS
QueueSessionのマネージャコンポーネントです。 org.jboss.seam.jms.topicSession- JMS
TopicSessionのマネージャコンポーネントです。
30.9. メール関連のコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.mail.mailSession- JavaMail
Sessionのマネージャコンポーネントです。 セッションを JNDI コンテキスト内で検索させるか (sessionJndiNameプロパティを設定)、 設定オプションから作成することができます。 後者の場合、hostは必須です。org.jboss.seam.mail.mailSession.host− 使用する SMTP サーバーのホスト名です。org.jboss.seam.mail.mailSession.port− 使用する SMTP サーバーのポートです。org.jboss.seam.mail.mailSession.username− SMTP サーバーの接続に使用するユーザー名です。org.jboss.seam.mail.mailSession.password− SMTP サーバーの接続に使用するパスワードです。org.jboss.seam.mail.mailSession.debug− JavaMail のデバッグ機能を有効にします (かなり冗長です)。org.jboss.seam.mail.mailSession.ssl− SMTP への SSL 接続を有効にします (デフォルトはポート 465)。org.jboss.seam.mail.mailSession.tls− メールセッションで TLS サポートを有効にします。デフォルトはtrueです。org.jboss.seam.mail.mailSession.sessionJndiName− JNDI にバインドされる javax.mail.Session と同じ名前です。これが与えられると他のプロパティはすべて無視されます。
30.10. 基盤となるコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
components.xml 内のそのコンポーネントで install="true" を設定するとインストールすることができます。
org.jboss.seam.core.init- このコンポーネントは Seam の初期化設定を含んでいます。 常にインストールされます。
org.jboss.seam.core.init.jndiPattern− セッション Bean の検索に使用される JNDI パターンです。org.jboss.seam.core.init.debug− Seam デバッグモードを有効にします。 実稼働ではfalseに設定してください。 デバッグが有効になっている状態でシステムに負荷がかかるとエラーが表示される場合があります。org.jboss.seam.core.init.clientSideConversations−trueに設定すると Seam は対話のコンテキスト変数をHttpSession内ではなくクライアント内に保存します。
org.jboss.seam.core.manager- Seam ページおよび対話コンテキスト管理用の内部コンポーネントです。 常にインストールされます。
org.jboss.seam.core.manager.conversationTimeout− ミリ秒単位で対話コンテキストのタイムアウトを設定します。org.jboss.seam.core.manager.concurrentRequestTimeout− 長期実行の対話コンテキストでロックの取得を試行しているスレッドの最大待機時間です。org.jboss.seam.core.manager.conversationIdParameter− 対話 ID の伝播に使用する要求パラメータです。 デフォルトはconversationIdです。org.jboss.seam.core.manager.conversationIsLongRunningParameter− 対話が長期実行であることを伝播するために使用する要求パラメータです。 デフォルトはconversationIsLongRunningです。org.jboss.seam.core.manager.defaultFlushMode− すべての Seam 管理永続コンテキストにデフォルトで設定されるフラッシュモードを設定します。 デフォルトではAUTOに設定されます。
org.jboss.seam.navigation.pages- Seam ワークスペース管理用の内部コンポーネントです。 常にインストールされます。
org.jboss.seam.navigation.pages.noConversationViewId− 対話エントリがサーバー側で見つからない場合にグローバルなリダイレクト先となるビュー ID を指定します。org.jboss.seam.navigation.pages.loginViewId− 未承認ユーザーが保護されたビューへのアクセスを試行する場合にグローバルなリダイレクト先となるビュー ID を指定します。org.jboss.seam.navigation.pages.httpPort− HTTP スキームが要求された場合にグローバルに使用するポートを指定します。org.jboss.seam.navigation.pages.httpsPort− HTTPS スキームが要求された場合にグローバルに使用するポートを指定します。org.jboss.seam.navigation.pages.resources−pages.xmlスタイルのリソースを検索するリソース一覧です。 デフォルトはWEB-INF/pages.xmlです。
org.jboss.seam.bpm.jbpm- このコンポーネントは
JbpmConfigurationをブートストラップします。 クラスorg.jboss.seam.bpm.Jbpmとしてインストールします。org.jboss.seam.bpm.jbpm.processDefinitions− ビジネスプロセスの編成に使用する jPDL ファイルのリソース名一覧を指定します。org.jboss.seam.bpm.jbpm.pageflowDefinitions− 対話ページフローの編成に使用する jPDL ファイルのリソース名一覧を指定します。
org.jboss.seam.core.conversationEntries- 要求間のアクティブな長期実行の対話を記録するセッションスコープの内部コンポーネントです。
org.jboss.seam.faces.facesPage- ページに関連付けられた対話コンテキストを記録するページスコープの内部コンポーネントです。
org.jboss.seam.persistence.persistenceContexts- 現在の対話に使用された永続コンテキストを記録する内部コンポーネントです。
org.jboss.seam.jms.queueConnection- JMS
QueueConnectionを管理します。これは管理QueueSenderがインストールされると必ずインストールされます。org.jboss.seam.jms.queueConnection.queueConnectionFactoryJndiName− JMSQueueConnectionFactoryの JNDI 名を指定します。 デフォルトはUIL2ConnectionFactoryです。
org.jboss.seam.jms.topicConnection- JMS
TopicConnectionを管理します。これは管理TopicPublisherがインストールされると必ずインストールされます。org.jboss.seam.jms.topicConnection.topicConnectionFactoryJndiName− JMSTopicConnectionFactoryの JNDI 名を指定します。 デフォルトはUIL2ConnectionFactoryです。
org.jboss.seam.persistence.persistenceProvider- JPA プロバイダの標準化されていない機能に対する抽象化レイヤです。
org.jboss.seam.core.validators- Hibernate Validator
ClassValidatorのインスタンスをキャッシュします。 org.jboss.seam.faces.validation- 検証が失敗または成功のどちらかをアプリケーションが判断できます。
org.jboss.seam.debug.introspector- Seam Debug Page のサポートです。
org.jboss.seam.debug.contexts- Seam Debug Page のサポートです。
org.jboss.seam.exception.exceptions- 例外処理用の内部コンポーネントです。
org.jboss.seam.transaction.transaction- トランザクションを制御し JTA 互換のインターフェースの背後にあるトランザクション管理の基礎となる実装を抽象化するための API です。
org.jboss.seam.faces.safeActions- アクション式がビュー内に存在するかどうかを確認することで、着信 URL 内のアクション式の安全性を判断します。
30.11. その他のコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.async.dispatcher- 非同期メソッドのステートレスセッション Bean をディスパッチします。
org.jboss.seam.core.image- イメージの操作および問い合わせに使用されます。
org.jboss.seam.core.pojoCache- PojoCache インスタンスのマネージャコンポーネントです。
org.jboss.seam.core.uiComponent- コンポーネント ID によりキー付けされた UIComponents のマップを管理します。
30.12. 特殊なコンポーネント リンクのコピーリンクがクリップボードにコピーされました!
components.xml 内の次の行では、Seam コンポーネントを 2 つインストールして、設定します。
bookingDatabase と userDatabase です。
- <entityManager>,
org.jboss.seam.persistence.ManagedPersistenceContext - 拡張永続コンテキストを持つ対話スコープで管理の
EntityManagerのマネージャコンポーネントです。- <entityManager>.entityManagerFactory −
EntityManagerFactoryのインスタンスに評価を行う値バインディング式です。<entityManager>.persistenceUnitJndiName − エンティティマネージャファクトリの JNDI 名です。 デフォルトではこれはjava:/です。<managedPersistenceContext>
- <entityManagerFactory>,
org.jboss.seam.persistence.EntityManagerFactory - JPA
EntityManagerFactoryを管理します。 EJB3 サポートの環境の外部で JPA を使用する場合に最適となります。entityManagerFactory.persistenceUnitName− 永続ユニット名です。
設定プロパティの詳細は API JavaDoc をご覧ください。 - <session>,
org.jboss.seam.persistence.ManagedSession - 対話スコープで管理の Hibernate
Sessionのマネージャコンポーネントです。- <session>.sessionFactory −
SessionFactoryのインスタンスに評価を行う値バインディング式です。<session>.sessionFactoryJndiName − セッションファクトリの JNDI 名です。 デフォルトはjava:/です。<managedSession>
- <sessionFactory>,
org.jboss.seam.persistence.HibernateSessionFactory - Hibernate
SessionFactoryを管理します。<sessionFactory>.cfgResourceName− 設定ファイルへのパスを指定します。デフォルトはhibernate.cfg.xmlです。
設定プロパティの詳細は API JavaDoc をご覧ください。 - <managedQueueSender>,
org.jboss.seam.jms.ManagedQueueSender - イベントスコープで管理の JMS
QueueSenderのマネージャコンポーネントです。- <managedQueueSender>.queueJndiName − JMS キューの JNDI 名です。
- <managedTopicPublisher>,
org.jboss.seam.jms.ManagedTopicPublisher - イベントスコープで管理の JMS
TopicPublisherのマネージャコンポーネントです。- <managedTopicPublisher>.topicJndiName − JMS トピックの JMDI 名です。
- <managedWorkingMemory>,
org.jboss.seam.drools.ManagedWorkingMemory - 対話スコープで管理の Drools
WorkingMemoryのマネージャコンポーネントです。- <managedWorkingMemory>.ruleBase −
RuleBaseのインスタンスに評価を行う値式です。
- <ruleBase>,
org.jboss.seam.drools.RuleBase - アプリケーションスコープの Drools
RuleBaseのマネージャコンポーネントです。 新しいルールの動的なインストールには対応しないため、 実稼働使用には適さない点に注意してください。- <ruleBase>.ruleFiles − Drools のルール郡を含むファイルの一覧です。<ruleBase>.dslFile − Drools DSL 定義です。
第31章 Seam JSF コントロール リンクのコピーリンクがクリップボードにコピーされました!
31.1. タグ リンクのコピーリンクがクリップボードにコピーされました!
s 名前空間を定義します (Facelets のみ)。
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib">
31.1.1. ナビゲーションコントロール リンクのコピーリンクがクリップボードにコピーされました!
31.1.1.1. リンクのコピーリンクがクリップボードにコピーされました!
value− ボタンのラベルです。action− アクションリスナーを指定するメソッドバインディングです。view− リンク先となる JSF ビュー ID を指定します。fragment− リンク先となるフラグメント識別子を指定します。disabled− リンクを無効にするかどうか指定します。propagation− 対話の伝播方式を指定します、begin、join、nest、none、endがあります。pageflow− 開始するページフロー定義を指定します (propagation="begin"またはpropagation="join"が使用される場合のみ有効)。
<s:button id="cancel" value="Cancel" action="#{hotelBooking.cancel}"/>
<s:button id="cancel" value="Cancel" action="#{hotelBooking.cancel}"/>
<s:link /> には、 view と action の両方が指定可能です。 この場合、指定されたビューへのリダイレクトが発生した時点でアクションが呼び出されます。
<s:button />ではアクションリスナー (デフォルトの JSF アクションリスナーも含む) の使用はサポートされていません。
31.1.1.2. リンクのコピーリンクがクリップボードにコピーされました!
<h:commandLink />, <s:button />.
31.1.1.3. リンクのコピーリンクがクリップボードにコピーされました!
#{task} で利用可能な場合、 出力リンク (または同様の JSF コントロール) にタスク ID を付加します。
31.1.1.4. リンクのコピーリンクがクリップボードにコピーされました!
<s:link />ではアクションリスナー (デフォルトの JSF アクションリスナーも含む) の使用はサポートされていません。
value− リンクラベルを指定します。action− アクションリスナーを指定するメソッドバインディングです。view− リンク先となる JSF ビュー ID を指定します。fragment− リンク先となるフラグメント識別子を指定します。disabled− リンクを無効にするかどうか指定します。propagation− 対話の伝播方式を指定します、begin、join、nest、none、endがあります。pageflow− 開始するページフロー定義を指定します (propagation="begin"またはpropagation="join"が使用される場合のみ有効)。
<s:link id="register" view="/register.xhtml" value="Register New User"/>
<s:link id="register" view="/register.xhtml" value="Register New User"/>
<s:link /> には、 view と action の両方が指定可能です。 この場合、指定されたビューへのリダイレクトが発生した時点でアクションが呼び出されます。
31.1.1.5. リンクのコピーリンクがクリップボードにコピーされました!
type— 対話の伝播方式を指定します、begin、join、nest、noneendがあります。pageflow− 開始するページフロー定義を指定します (propagation="begin"またはpropagation="join"が使用される場合のみ有効)。
<h:commandButton value="Apply" action="#{personHome.update}">
<s:conversationPropagation type="join" />
</h:commandButton>
<h:commandButton value="Apply" action="#{personHome.update}">
<s:conversationPropagation type="join" />
</h:commandButton>
31.1.1.6. リンクのコピーリンクがクリップボードにコピーされました!
<h:commandButton />、 <a:commandButton />、 <tr:commandButton /> など、 ボタンの内側にのみネストが可能です。
<h:commandButton id="foo" value="Foo" action="#{manager.foo}">
<s:defaultAction />
</h:commandButton>
<h:commandButton id="foo" value="Foo" action="#{manager.foo}">
<s:defaultAction />
</h:commandButton>
31.1.2. コンバータとバリデータ リンクのコピーリンクがクリップボードにコピーされました!
31.1.2.1. リンクのコピーリンクがクリップボードにコピーされました!
<h:outputText value="#{item.orderDate}">
<s:convertDateTime type="both" dateStyle="full"/>
</h:outputText>
<h:outputText value="#{item.orderDate}">
<s:convertDateTime type="both" dateStyle="full"/>
</h:outputText>
31.1.2.2. リンクのコピーリンクがクリップボードにコピーされました!
entityManager という名前でなければなりません。 この名前が付いていない場合は components.xml で変更します。
<components xmlns="http://jboss.com/products/seam/components"
xmlns:ui="http://jboss.com/products/seam/ui">
<ui:jpa-entity-loader entity-manager="#{em}" />
<components xmlns="http://jboss.com/products/seam/components"
xmlns:ui="http://jboss.com/products/seam/ui">
<ui:jpa-entity-loader entity-manager="#{em}" />
components.xml でも設定する必要があります。
<components xmlns="http://jboss.com/products/seam/components"
xmlns:ui="http://jboss.com/products/seam/ui">
<ui:hibernate-entity-loader />
<components xmlns="http://jboss.com/products/seam/components"
xmlns:ui="http://jboss.com/products/seam/ui">
<ui:hibernate-entity-loader />
session という名前でなければなりません。 この名前が付いていない場合は components.xml で変更します。
<components xmlns="http://jboss.com/products/seam/components"
xmlns:ui="http://jboss.com/products/seam/ui">
<ui:hibernate-entity-loader session="#{hibernateSession}" />
<components xmlns="http://jboss.com/products/seam/components"
xmlns:ui="http://jboss.com/products/seam/ui">
<ui:hibernate-entity-loader session="#{hibernateSession}" />
components.xml でそれぞれのエンティティマネージャに対してこのエンティティコンバータのコピーを作成します。 エンティティコンバータはエンティティローダーに委譲して次のような永続化操作を行います。
31.1.2.3. リンクのコピーリンクがクリップボードにコピーされました!
31.1.2.4. リンクのコピーリンクがクリップボードにコピーされました!
java.util.concurrent.atomic.AtomicBoolean 用の javax.faces.convert.Converter です。
<h:outputText value="#{item.valid}">
<s:convertAtomicBoolean />
</h:outputText>
<h:outputText value="#{item.valid}">
<s:convertAtomicBoolean />
</h:outputText>
31.1.2.5. リンクのコピーリンクがクリップボードにコピーされました!
java.util.concurrent.atomic.AtomicInteger 用の javax.faces.convert.Converter です。
<h:outputText value="#{item.id}">
<s:convertAtomicInteger />
</h:outputText>
<h:outputText value="#{item.id}">
<s:convertAtomicInteger />
</h:outputText>
31.1.2.6. リンクのコピーリンクがクリップボードにコピーされました!
java.util.concurrent.atomic.AtomicLong 用の javax.faces.convert.Converter です。
<h:outputText value="#{item.id}">
<s:convertAtomicLong />
</h:outputText>
<h:outputText value="#{item.id}">
<s:convertAtomicLong />
</h:outputText>
31.1.2.7. リンクのコピーリンクがクリップボードにコピーされました!
for− 検証の対象となるコントロールの ID です。message− 失敗時に表示されるメッセージです。required— False は値がフィールドで入力されたかのチェックを無効にします。messageId− 失敗時に表示するメッセージ ID です。operator— 値の比較時に使用する演算子です。 有効な演算子は次のとおりです。equal—value.equals(forValue)を検証します。not_equal—!value.equals(forValue)を検証します。greater— ((Comparable)value).compareTo(forValue) > 0 を検証します。greater_or_equal— ((Comparable)value).compareTo(forValue) >= 0 を検証します。less— ((Comparable)value).compareTo(forValue) < 0 を検証します。less_or_equal— ((Comparable)value).compareTo(forValue) <= 0 を検証します。
<h:inputText id="name" value="#{bean.name}"/>
<h:inputText id="nameVerification" >
<s:validateEquality for="name" />
</h:inputText>
<h:inputText id="name" value="#{bean.name}"/>
<h:inputText id="nameVerification" >
<s:validateEquality for="name" />
</h:inputText>
31.1.2.8. リンクのコピーリンクがクリップボードにコピーされました!
<h:inputText id="userName" required="true" value="#{customer.userName}">
<s:validate />
</h:inputText>
<h:message for="userName" styleClass="error" />
<h:inputText id="userName" required="true" value="#{customer.userName}">
<s:validate />
</h:inputText>
<h:message for="userName" styleClass="error" />
31.1.2.9. リンクのコピーリンクがクリップボードにコピーされました!
31.1.3. フォーマット リンクのコピーリンクがクリップボードにコピーされました!
31.1.3.1. リンクのコピーリンクがクリップボードにコピーされました!
required="true" に設定されている場合、 JSF 入力フィールドを「装飾」します。
template− コンポーネントの装飾に使用される Facelet テンプレートです。enclose—trueにすると、 入力フィールドの装飾に使用されたテンプレートが「element」属性で指定されたエレメントで囲まれます (デフォルトではdivエレメントです)。element— 入力フィールドを装飾するテンプレートを囲むエレメントです。 デフォルトではテンプレートはdivエレメントで囲まれます。
#{invalid} と #{required} が s:decorate の内部で利用可能です。 装飾された入力コンポーネントが required に設定されると #{required} は true と評価されます。 また、 検証エラーが発生すると、#{invalid} は true と評価されます。
<s:decorate template="edit.xhtml">
<ui:define name="label">Country:</ui:define>
<h:inputText value="#{location.country}" required="true"/>
</s:decorate>
<s:decorate template="edit.xhtml">
<ui:define name="label">Country:</ui:define>
<h:inputText value="#{location.country}" required="true"/>
</s:decorate>
31.1.3.2. リンクのコピーリンクがクリップボードにコピーされました!
<div> をレンダリングします。
<s:div rendered="#{selectedMember == null}">
Sorry, but this member does not exist.
</s:div>
<s:div rendered="#{selectedMember == null}">
Sorry, but this member does not exist.
</s:div>
31.1.3.3. リンクのコピーリンクがクリップボードにコピーされました!
<span> をレンダリングします。
title− span のタイトルです。
<s:span styleClass="required" rendered="#{required}" title="Small tooltip">
*
</s:span>
<s:span styleClass="required" rendered="#{required}" title="Small tooltip">
*
</s:span>
31.1.3.4. リンクのコピーリンクがクリップボードにコピーされました!
<s:fragment rendered="#{auction.highBidder ne null}">
Current bid:
</s:fragment>
<s:fragment rendered="#{auction.highBidder ne null}">
Current bid:
</s:fragment>
31.1.3.5. リンクのコピーリンクがクリップボードにコピーされました!
<label> タグの内側に配置され、 最も近い JSF 入力コンポーネントと関連付けられます。 <s:decorate> と併用されることがよくあります。
style− コントロールのスタイルです。styleClass− コントロールのスタイルクラスです。
<s:label styleClass="label"> Country: </s:label>
<h:inputText value="#{location.country}" required="true"/>
<s:label styleClass="label"> Country: </s:label>
<h:inputText value="#{location.country}" required="true"/>
31.1.3.6. リンクのコピーリンクがクリップボードにコピーされました!
31.1.4. Seam Text リンクのコピーリンクがクリップボードにコピーされました!
31.1.4.2. リンクのコピーリンクがクリップボードにコピーされました!
value− レンダリングするリッチテキストマークアップを指定する EL 式です。
<s:formattedText value="#{blog.text}"/>
<s:formattedText value="#{blog.text}"/>
31.1.5. フォームのサポート リンクのコピーリンクがクリップボードにコピーされました!
31.1.5.1. リンクのコピーリンクがクリップボードにコピーされました!
requireSession— トークンをセッションにバインドさせるためセッション ID をフォーム署名に含ませるかどうかを示します。 デフォルト値はfalseですが、 Facelets が「build before restore」モードの場合にしか使用されないはずです (「build before restore」は JSF 2.0 ではデフォルトのモードです)。enableCookieNotice— クッキーがブラウザで有効であることを確認するために JavaScript チェックがページに挿入されるべきであると示します。 クッキーが有効でないとフォームの送信は機能しないという通知をユーザーに表示します。 デフォルト値はfalseです。allowMultiplePosts— 同じフォームを同じ署名を使って複数送信が可能かどうかを示します (ビューは変更なし)。 フォームがそれ自体または UIToken コンポーネントをレンダリングしないで AJAX 呼び出しを行っている場合に必要とされることが多くあります。 UIToken コンポーネントが処理されるであろう AJAX の呼び出し時に UIToken コンポーネントを再度レンダリングした方がよいでしょう。 デフォルト値はfalseです。
<h:form> <s:token enableCookieNotice="true" requireSession="false"/> ... </h:form>
<h:form>
<s:token enableCookieNotice="true" requireSession="false"/>
...
</h:form>
31.1.5.2. リンクのコピーリンクがクリップボードにコピーされました!
SelectItem を作成します。
enumValue− 列挙値の文字列表現です。label−SelectItemをレンダリングするときに使用するラベルです。
31.1.5.3. リンクのコピーリンクがクリップボードにコピーされました!
List<SelectItem> を作成します。
value−List<SelectItem>に格納されるデータを指定する EL 式です。var− 反復中に現在のオブジェクトを保持するローカル変数の名前を定義します。label−SelectItemをレンダリングするときに使用するラベルです。var変数の参照が可能です。itemValue− この選択肢を選ぶとサーバに戻される値を指定します。 これはオプション属性です。 含ませるとvarが使用されるデフォルトのオブジェクトになります。var変数の参照が可能です。disabled−trueの場合、SelectItemが無効としてレンダリングされます。var変数の参照が可能です。noSelectionLabel− 一覧の冒頭に記載する (オプションの) ラベルを指定します。 この値を選択し、 またrequired="true"も指定すると検証エラーとなります。hideNoSelectionLabel− true の場合、 値が選択されているとnoSelectionLabelは非表示になります。
<h:selectOneMenu value="#{person.age}" converter="ageConverter">
<s:selectItems value="#{ages}" var="age" label="#{age}" />
</h:selectOneMenu>
<h:selectOneMenu value="#{person.age}" converter="ageConverter">
<s:selectItems value="#{ages}" var="age" label="#{age}" />
</h:selectOneMenu>
31.1.5.4. リンクのコピーリンクがクリップボードにコピーされました!
multipart/form-data にしてフォーム内で使用しなければなりません。
<h:form enctype="multipart/form-data">
<h:form enctype="multipart/form-data">
web.xml 内で設定しなければなりません。
components.xml では、 次のようなマルチパート要求用の設定オプションが設定できます。
createTempFiles−trueの場合、アップロードされたファイルはメモリではなく一時ファイルに保存されます。maxRequestSize− ファイルアップロード要求のバイト単位の最大サイズです。
<component class="org.jboss.seam.web.MultipartFilter"> <property name="createTempFiles">true</property> <property name="maxRequestSize">1000000</property> </component>
<component class="org.jboss.seam.web.MultipartFilter">
<property name="createTempFiles">true</property>
<property name="maxRequestSize">1000000</property>
</component>
data− バイナリのファイルデータを受け取る値バインディングを指定します。 受け取るフィールドはbyte[]またはInputStreamとして宣言されている必要があります。contentType− ファイルのコンテンツタイプを受け取る値バインディングを指定するオプションの属性です。fileName− ファイル名を受け取る値バインディングを指定するオプションの属性です。fileSize− ファイルサイズを受け取る値バインディングを指定するオプションの属性です。accept− 受け入れ可能なコンテンツタイプをコンマで区切った一覧です。 たとえば、"images/png,images/jpg"、"images/*"などです。 記載されているタイプはブラウザによってサポートされない場合があります。style− コントロールのスタイルです。styleClass− コントロールのスタイルクラスです。
<s:fileUpload id="picture"
data="#{register.picture}" accept="image/png"
contentType="#{register.pictureContentType}" />
<s:fileUpload id="picture"
data="#{register.picture}" accept="image/png"
contentType="#{register.pictureContentType}" />
31.1.6. その他 リンクのコピーリンクがクリップボードにコピーされました!
31.1.6.1. リンクのコピーリンクがクリップボードにコピーされました!
<s:cache> は実際には組み込みの pojoCache コンポーネントで管理される JBoss Cache のインスタンスを使用するので注意してください。
key− レンダリングされたコンテンツをキャッシュするキーです。 値式がよく使用されます。 例えば、 ドキュメントを表示するページフラグメントをキャッシュする場合、key="Document-#{document.id}"のように使います。enabled− キャッシュを使うべきかどうか決定する値式です。region− 使用する JBoss Cache のノードを指定します。 ノード毎に異なる有効期限ポリシーを持つことができます。
31.1.6.2. リンクのコピーリンクがクリップボードにコピーされました!
web.xml を設定する必要があります。
data— ダウンロードすべきデータを指定します。 java.util.File、 InputStream、 バイトアレイなどになります。fileName− 処理するファイルのファイル名です。contentType− ダウンロードするファイルのコンテンツタイプです。disposition— 使用するディスポジションです。 デフォルトのディスポジションはinlineです。
<s:resource xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
data="#{resources.data}" contentType="#{resources.contentType}"
fileName="#{resources.fileName}" />
<s:resource xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
data="#{resources.data}" contentType="#{resources.contentType}"
fileName="#{resources.fileName}" />
resources という名前の Bean はバッキング Bean であり、 要求パラメータの場合、 特定のファイルを処理します。 s:download を参照してください。
31.1.6.3. リンクのコピーリンクがクリップボードにコピーされました!
<s:resource> への RESTful リンクをビルドします。 ネストされた f:param はその URL を構成します。
src— ファイルを処理するリソースファイルです。
<s:download src="/resources.xhtml">
<f:param name="fileId" value="#{someBean.downloadableFileId}"/>
</s:download>
<s:download src="/resources.xhtml">
<f:param name="fileId" value="#{someBean.downloadableFileId}"/>
</s:download>
http://localhost/resources.seam?fileId=1 と同じようなフォームのリンクを生成します。
31.1.6.4. リンクのコピーリンクがクリップボードにコピーされました!
<h:graphicImage> です。 さらに画像の変換も可能です。
<h:graphicImage> の属性はすべてサポートされる他、 以下もサポートされます。
value− 表示する画像を指定します。 パスを表すString(クラスパスからロードされます)、byte[]、java.io.File、java.io.InputStream、java.net.URLが指定可能です。 現在サポートされている画像フォーマットはimage/bmp、image/png、image/jpegとimage/gifです。fileName— 画像のファイル名を指定します。 この名前は一意にしてください。 指定しないと画像に一意のファイル名が生成されます。
<s:transformImageSize>width− 画像の新しい幅を指定します。height− 画像の新しい高さを指定します。maintainRatio−widthかheightのいずれかを指定した状態でtrueにすると、 画像はリサイズされてheight:widthの縦横比を維持します。factor− 与えられた係数で画像を拡大縮小します。
<s:transformImageBlur>radius− 与えられた半径でコンボリューションブラーを実行します。
<s:transformImageType>contentType− 画像のタイプをimage/jpegまたはimage/pngに変更します。
org.jboss.seam.ui.graphicImage.ImageTransform を実装する UIComponent を作成します。 applyTransform() メソッド内で image.getBufferedImage() を使って元の画像を取得し、 image.setBufferedImage() で変換した画像を設定します。 変換はビューに指定された順序で適用されます。
<s:graphicImage rendered="#{auction.image ne null}"
value="#{auction.image.data}">
<s:transformImageSize width="200" maintainRatio="true"/>
</s:graphicImage>
<s:graphicImage rendered="#{auction.image ne null}"
value="#{auction.image.data}">
<s:transformImageSize width="200" maintainRatio="true"/>
</s:graphicImage>
31.1.6.5. リンクのコピーリンクがクリップボードにコピーされました!
include− コンポーネント名 (または完全修飾クラス名)をコンマで区切った一覧です。 Seam Remoting の Javascript スタブを生成します。 詳しくは 24章リモーティング を参照してください。
<s:remote include="customerAction,accountAction,com.acme.MyBean"/>
<s:remote include="customerAction,accountAction,com.acme.MyBean"/>
31.2. アノテーション リンクのコピーリンクがクリップボードにコピーされました!
@ConverterCopy to Clipboard Copied! Toggle word wrap Toggle overflow <h:inputText value="#{shop.item}" converter="itemConverter" /><h:inputText value="#{shop.item}" converter="itemConverter" />Copy to Clipboard Copied! Toggle word wrap Toggle overflow Seam コンポーネントを JSF コンバータとして登録します。 上記では、 値をそのオブジェクト表現に変換するときにコンバータが JTA トランザクション内の JPA EntityManager にアクセスします。@ValidatorCopy to Clipboard Copied! Toggle word wrap Toggle overflow <h:inputText value="#{shop.item}" validator="itemValidator" /><h:inputText value="#{shop.item}" validator="itemValidator" />Copy to Clipboard Copied! Toggle word wrap Toggle overflow Seam コンポーネントを JSF バリデータとして登録します。 上記では、 バリデータは別の Seam コンポーネントをインジェクトし、 インジェクトされたコンポーネントが値の検証に使用されます。
第32章 JBoss EL リンクのコピーリンクがクリップボードにコピーされました!
32.1. パラメータ化された式 リンクのコピーリンクがクリップボードにコピーされました!
<h:commandButton action="#{hotelBooking.bookHotel(hotel)}"
value="Book Hotel"/>
<h:commandButton action="#{hotelBooking.bookHotel(hotel)}"
value="Book Hotel"/>
32.1.1. 使い方 リンクのコピーリンクがクリップボードにコピーされました!
<h:commandButton action="#{hotelBooking.bookHotel(hotel, user)}"
value="Book Hotel"/>
<h:commandButton action="#{hotelBooking.bookHotel(hotel, user)}"
value="Book Hotel"/>
hotel と user は値式として評価され、コンポーネントの bookHotel() メソッドに渡されます。
<h:commandButton action="#{hotelBooking.bookHotel(hotel.id,
user.username)}"
value="Book Hotel"/>
<h:commandButton action="#{hotelBooking.bookHotel(hotel.id,
user.username)}"
value="Book Hotel"/>
hotel.id および user.username が保存され、 ページがサブミットされるときに値式として評価されます。 パラメータとしてオブジェクトを渡すことはできません。
null 引数を付けて呼び出されます。
<h:commandLink action="#{printer.println('Hello world!')}"
value="Hello"/>
<h:commandLink action="#{printer.println('Hello world!')}"
value="Hello"/>
rendered 属性など)。しかし、多くのオブジェクトは適切な名前が付いたプロパティアクセサを持たず、パラメータを必要としません。
<h:outputText value="#{person.name}"
rendered="#{person.name.length() > 5}" />
<h:outputText value="#{person.name}"
rendered="#{person.name.length() > 5}" />
#{searchResults.size()}
#{searchResults.size()}
#{obj.property} 形式の式は #{obj.getProperty()} 式と同一となります。
productsByColorMethod を呼び出しています。
#{controller.productsByColor('blue')}
#{controller.productsByColor('blue')}
32.1.2. 制約とヒント リンクのコピーリンクがクリップボードにコピーされました!
- JSP 2.1 との非互換性 − JBoss EL は現在 JSP 2.1 との併用はできません。 コンパイラがパラメータ付きの式を拒否するためです。 JSF 1.2 でこの拡張機能を使用したい場合は Facelets を使用する必要があります。 この拡張機能は JSP 2.0 では正常に動作します。
- 反復コンポーネント内での使用 −
<c:forEach />や<ui:repeat />といったコンポーネントはリストまたはアレイに対して反復を行い、 一覧内の各アイテムをネストされるコンポーネントに公開します。これは<h:commandButton />または<h:commandLink />を使った行を選択している場合に効果的です。@Factory("items") public List<Item> getItems() { return entityManager.createQuery("select ...").getResultList(); }@Factory("items") public List<Item> getItems() { return entityManager.createQuery("select ...").getResultList(); }Copy to Clipboard Copied! Toggle word wrap Toggle overflow Copy to Clipboard Copied! Toggle word wrap Toggle overflow ただし、<s:link />や<s:button />を使用したい場合はアイテムをDataModelとして公開して<dataTable />(または<rich:dataTable />のようなコンポーネントセットと同等) を使用しなければなりません。<s:link />または<s:button />のいずれもフォームをサブミットしないためブックマーク可能なリンクを生成しません。 アクションメソッドが呼び出された場合にそのアイテムを再度作成するためには追加のパラメータが必要です。DataModelで支えられるデータテーブルが使用される場合のみこのパラメータは追加可能です。 - Java コードから
MethodExpressionを呼び出す − 通常、MethodExpressionが作成されるとパラメータタイプが JSF によって渡されます。ただし、メソッドバインディングでは JSF は渡すパラメータがないとみなします。この拡張機能では、 式の評価が終了するまでパラメータタイプを知ることはできません。これにより以下の 2 つの結果が生じます。- Java コードで
MethodExpressionを呼び出すとき、渡すパラメータが無視される場合があります。 式で定義されたパラメータが優先されます。 - 通常、
methodExpression.getMethodInfo().getParamTypes()はいつでも安全に呼び出すことができます。パラメータを持つ式に関しては、まずMethodExpressionを呼び出してから、getParamTypes()を呼び出すようにしてください。
上記のようなケースは非常に稀であり、 Java コードでMethodExpressionを手作業で呼び出したい場合にのみ適用されます。
32.2. プロジェクション リンクのコピーリンクがクリップボードにコピーされました!
#{company.departments}
#{company.departments}
#{company.departments.{d|d.name}}
#{company.departments.{d|d.name}}
d.name 式が評価され、 d を部署のオブジェクトへのエイリアスとして使用します。 この式の結果は文字列値の一覧となります。
#{company.departments.{d|d.size()}}
#{company.departments.{d|d.size()}}
#{company.departments.{d|d.employees.{emp|emp.lastName}}}
#{company.departments.{d|d.employees.{emp|emp.lastName}}}
#{company.departments.{d|d.employees}}
#{company.departments.{d|d.employees}}
#{company.departments.{d|d.employees.{e|e}}}
#{company.departments.{d|d.employees.{e|e}}}
第33章 クラスター化と EJB 非活性化 リンクのコピーリンクがクリップボードにコピーされました!
33.1. クラスタ化 リンクのコピーリンクがクリップボードにコピーされました!
33.1.1. クラスタ化用のプログラミング リンクのコピーリンクがクリップボードにコピーされました!
org.jboss.seam.core.Mutable インターフェースを実装しなければなりません。 コントラクトの一部としてコンポーネントは dirtyflag イベントを管理する必要があり、 これが保存しなければならないフォームにユーザーが変更を加えたかどうかを示します。 このイベントは clearDirty() メソッドにより報告およびリセットが行われ、 このメソッドはコンポーネントの複製が必要かどうかを確定するため呼び出されます。 これによりオブジェクトに対するあらゆる変更に対しセッション属性の追加や削除に Servlet API を使用する必要がなくなります。
@PrePassivate メソッドで null に設定されていない限り、 ステートフルコンポーネントのフィールドはすべてシリアライズ可能でなければなりません (EJB または JavaBean)。 transient または nullified のフィールドの値は @PostActivate メソッドで復元することができます。
List.subList を使用する場合、 問題が発生する可能性があります。 作成されたリストがシリアライズできないためです。 オブジェクトを自動的に作成するいくつかのメソッドにも同様の状況が発生することがあります。 java.io.NotSerializableException が発生した場合は、 この例外にブレークポイントを配置しデバッグモードでアプリケーションサーバーを稼働して問題となるメソッドを探します。
注記
33.1.2. Seam アプリケーションをセッション複製で JBoss AS クラスタへデプロイ リンクのコピーリンクがクリップボードにコピーされました!
192.168.1.2 と 192.168.1.3 であると仮定します。 両方のノードが要求に応答しセッションと通信していることを確認しやすいよう意図的に mod_jk ロードバランサーは使用しませんでした。
vehicles.war のデプロイメントおよびそれに該当するデータソース vehiclesDatasource から生成されました。 Booking サンプルはこのプロセスに完全に対応しています。クラスタへのデプロイ方法に関する説明は examples/booking/readme.txt ファイルでご覧頂けます。
注記
iptables のルールを変更してください (root 権限)。 IP アドレスが 192.168.1.x とした場合、 コマンドは次のようになります。
/sbin/iptables -I RH-Firewall-1-INPUT 5 -p udp -d 224.0.0.0/4 -j ACCEPT /sbin/iptables -I RH-Firewall-1-INPUT 9 -p udp -s 192.168.1.0/24 -j ACCEPT /sbin/iptables -I RH-Firewall-1-INPUT 10 -p tcp -s 192.168.1.0/24 -j ACCEPT /etc/init.d/iptables save
/sbin/iptables -I RH-Firewall-1-INPUT 5 -p udp -d 224.0.0.0/4 -j ACCEPT
/sbin/iptables -I RH-Firewall-1-INPUT 9 -p udp -s 192.168.1.0/24 -j ACCEPT
/sbin/iptables -I RH-Firewall-1-INPUT 10 -p tcp -s 192.168.1.0/24 -j ACCEPT
/etc/init.d/iptables save
注記
@Clustered (JBoss EJB 3.0 アノテーション API より) アノテーションを付与するか jboss.xml 記述子で clustered の印を付ける必要があります。 詳細については Booking サンプルを参照してください。
33.1.3. チュートリアル リンクのコピーリンクがクリップボードにコピーされました!
- JBoss AS のインスタンスを 2 つ作成します (
zipを 2 度展開するだけです)。HSQLDB を使用しない場合は JDBC ドライバを両方のインスタンスのserver/all/lib/にデプロイします。 WEB-INF/web.xmlに最初の子エレメントとして<distributable/>を追加します。org.jboss.seam.core.initにあるdistributableプロパティをtrueに設定してManagedEntityInterceptorを有効にします (つまり、WEB-INF/components.xmlに<core:init distributable="true">と設定します)。- 使用可能な IP アドレスが 2 つあることを確認します (同じインターフェースに 2 台のコンピュータ、 2 枚のネットワークカード、 または 2 つの IP アドレスがバインドされているということです)。2 つの IP アドレスは
192.168.1.2と192.168.1.3と仮定します。 - 最初の IP でマスターとなる JBoss AS のインスタンスを起動します。
./bin/run.sh -c all -b 192.168.1.2
./bin/run.sh -c all -b 192.168.1.2Copy to Clipboard Copied! Toggle word wrap Toggle overflow ログはクラスタメンバーが 1 つ、 他のメンバーはゼロであると報告するはずです。 - スレーブとなる JBoss AS インスタンスの
server/all/farmディレクトリは空であることを確認します。 - スレーブの JBoss AS インスタンスを 2 番目の IP で起動します。
./bin/run.sh -c all -b 192.168.1.3
./bin/run.sh -c all -b 192.168.1.3Copy to Clipboard Copied! Toggle word wrap Toggle overflow ログはクラスタメンバーが 2 つ、 他のメンバーが 1 つであると報告するはずです。 また、 マスターインスタンスから取得されている状態を表示します。 -ds.xmlをマスターインスタンスのserver/all/farmにデプロイします。このデプロイメントの確認がマスターインスタンスのログに表示されるはずです。 スレーブインスタンスに対するデプロイメント確認の該当メッセージが表示されるはずです。- アプリケーションを server/all/farm ディレクトリにデプロイします。 通常のアプリケーション起動メッセージが終了すると、マスターインスタンスのログにデプロイメントの確認が表示されるはずです。 スレーブインスタンスのログはデプロイメントを確認する該当メッセージを表示します (デプロイされたアーカイブが転送されるのに最長 3 分間待つ必要がある場合があります)。
33.1.4. JBoss AS クラスタで稼働しているアプリケーションの配信可能なサービスの検証 リンクのコピーリンクがクリップボードにコピーされました!
- Category: jboss.cache
- Entry: config=standard-session-cache,service=Cache
- Method: printDetails()
printDetails() メソッドを呼び出します。 これによりアクティブな HTTP Session のツリーが表示されます。 ブラウザで使用しているセッションがツリーにあるセッションのいずれかに該当していることを確認します。
;jsessionid=XXXX を置き IP アドレスを変更して 2 番目のインスタンスの URL を構成します (セッションが別のインスタンスに引き継がれたのがわかるはずです)。
server/all/farm ディレクトリからデプロイされたアプリケーションを削除してインスタンスを再起動します。
HttpSessionActivationListener インターフェースのメソッドが使用できます (EJB 以外の全コンポーネントで自動的に登録されます)。
public void sessionWillPassivate(HttpSessionEvent e); public void sessionDidActivate(HttpSessionEvent e);
public void sessionWillPassivate(HttpSessionEvent e);
public void sessionDidActivate(HttpSessionEvent e);
@PrePassivate と @PostActivate のマークをそれぞれ付けることもできます。 不活性化は各要求の最後に発生しますが、活性化はノードが呼び出されたときに発生するのを忘れないようにしてください。
dirtyflag の管理のみで、 あとは Seam が JPA エンティティのインスタンスを処理してくれます。
33.2. EJB 非活性化と ManagedEntityInterceptor リンクのコピーリンクがクリップボードにコピーされました!
ManagedEntityInterceptor (MEI) は Seam ではオプションのインターセプタです。 有効にすると対話スコープのコンポーネントに適用されます。 MEI を有効にするには org.jboss.seam.init.core コンポーネントで distributable を true に設定します。 また、 次のコンポーネント宣言を components.xml ファイルに追加または更新することができます。
<core:init distributable="true"/>
<core:init distributable="true"/>
33.2.1. 非活性化と永続性の衝突 リンクのコピーリンクがクリップボードにコピーされました!
EntityManager#flush())。
33.2.2. ケース 1: EJB 非活性化の存続 リンクのコピーリンクがクリップボードにコピーされました!
@PersistenceContext(EXTENDED) アノテーションを付与されたステートフルセッション Bean にインジェクトされる EntityManager は、ステートフルセッション Bean にバインドされ Bean の寿命を通してアクティブであり続けます。 @In アノテーションでインジェクトされる EntityManager は Seam によって管理され対話コンテキストに直接保存されるため、 対話 の間はアクティブであり続け、 ステートフルセッション Bean とは無関係になります。
重要
33.2.3. ケース 2: HTTP セッション複製の存続 リンクのコピーリンクがクリップボードにコピーされました!
重要
第34章 パフォーマンス調整 リンクのコピーリンクがクリップボードにコピーされました!
34.1. インターセプタの迂回 リンクのコピーリンクがクリップボードにコピーされました!
ui:repeat などの反復コントロールの場合、 参照される Seam コンポーネントの呼び出しが行われるたびに完全なインターセプタスタックが呼び出されます。特にコンポーネントが何度もアクセスされると、これにより大幅にパフォーマンスが低下することがあります。 呼び出される Seam コンポーネントのインターセプタスタックを無効にすることでパフォーマンスを向上させることができます。 コンポーネントクラスに @BypassInterceptors アノテーションを付与します。
警告
@BypassInterceptors の付いたコンポーネントはすべてバイジェクション、 アノテーション付きセキュリティ制限、 同期などの機能は使用できない点に注意してください。 ただし、 通常は @In でコンポーネントをインジェクトする代わりに Component.getInstance() を使用するなどこれらの機能を補う手段があります。
第35章 Seam アプリケーションのテスト リンクのコピーリンクがクリップボードにコピーされました!
35.1. Seam コンポーネントのユニットテスト リンクのコピーリンクがクリップボードにコピーされました!
calculateTotal メソッドをテストすることができます。
35.2. Seam コンポーネントの統合テスト リンクのコピーリンクがクリップボードにコピーされました!
35.2.1. モックを使用した統合テスト リンクのコピーリンクがクリップボードにコピーされました!
@Name("paymentProcessor")
public class PaymentProcessor {
public boolean processPayment(Payment payment) { .... }
}
@Name("paymentProcessor")
public class PaymentProcessor {
public boolean processPayment(Payment payment) { .... }
}
MOCK の優先度はアプリケーションコンポーネントのデフォルト優先度より高くなるため、 モック実装がクラスパスにあるときは必ず Seam はそれをインストールします。 実稼働環境にデプロイする場合はモック実装は存在しないので、 実際のコンポーネントがインストールされます。
35.3. Seam アプリケーションのユーザーインタラクション統合テスト リンクのコピーリンクがクリップボードにコピーされました!
SeamTest を使用して擬似 JSF 環境で スクリプト化した テストを記述することができます。 スクリプト化したテストは、 ビューと Seam コンポーネント間のやりとりを再現するため、 テスト中は JSF 実装の役割を演じることになります。 この方法ならビュー以外のあらゆるものすべてがテスト可能です。
SeamTest を拡張し、コンポーネントに Seam 環境を提供し、テストスクリプトは SeamTest.FacesRequest を拡張する匿名クラスとして記述されています。 これにより模倣された JSF 要求ライフサイクルを提供しています (GET 要求をテストする SeamTest.NonFacesRequest もあります)。コードには各種の JSF フェーズ用に名前が付けられたメソッドが含まれ、 コンポーネントに対して JSF が行うであろう呼び出しを模倣します。 さらに、さまざまなアサーションもあります。
35.3.1. 設定 リンクのコピーリンクがクリップボードにコピーされました!
| グループ ID | アーティファクト ID | Seam での場所 |
|---|---|---|
org.jboss.seam.embedded | hibernate-all | lib/test/hibernate-all.jar |
org.jboss.seam.embedded | jboss-embedded-all | lib/test/jboss-embedded-all.jar |
org.jboss.seam.embedded | thirdparty-all | lib/test/thirdparty-all.jar |
org.jboss.seam.embedded | jboss-embedded-api | lib/jboss-embedded-api.jar |
org.jboss.seam | jboss-seam | lib/jboss-seam.jar |
org.jboss.el | jboss-el | lib/jboss-el.jar |
javax.faces | jsf-api | lib/jsf-api.jar |
javax.el | el-api | lib/el-api.jar |
javax.activation | javax.activation | lib/activation.jar |
lib/ にあるコンパイル時の JBoss AS 依存 (jboss-system.jar など) をクラスパスに置かないでください。必要に応じて Drools や jBPM などの依存を追加してください。
bootstrap/ ディレクトリには Embedded JBoss の設定が含まれているため、それをクラスパスに含める必要があります。
jar ファイル、 プロジェクト、 テストの他、 JPA および Seam の設定ファイル郡もクラスパスに含めてください。 Seam は Embedded JBoss に指示して seam.properties を持つリソース (JAR やディレクトリ) はすべてそのルートにデプロイさせます。 ビルドしたプロジェクトを含むディレクトリ構造がデプロイ可能なアーカイブのそれに似ていない場合は、各リソースに seam.properties を含ませる必要があります。
java:/DefaultDS (Embedded JBoss で HSQL データソースにビルドされたもの) をテストに使用します。 別のデータソースを使用する場合は、 foo-ds.xml を bootstrap/deploy ディレクトリに置いてください。
35.3.2. 別のテストフレームワークでの SeamTest の使用 リンクのコピーリンクがクリップボードにコピーされました!
AbstractSeamTest の実装を与える必要があります。
- それぞれのテストメソッドの前に
super.begin()を呼び出します。 - それぞれのテストメソッドの後に
super.end()を呼び出します。 - 統合テスト環境を設定する
super.setupClass()を呼び出します。 いずれのテストメソッドよりも先にこれを呼び出してください。 - 統合テスト環境を消去する
super.cleanupClass()を呼び出します。 - 統合テストの開始時に
super.startSeam()を呼び出して Seam を起動します。 - 統合テストの終了時に
super.stopSeam()を呼び出して Seam を正しくシャットダウンします。
35.3.3. モックデータを利用した統合テスト リンクのコピーリンクがクリップボードにコピーされました!
SeamTest ではなく DBUnitSeamTest を拡張します。
prepareDBUnitOperations() を無効にしてデータセットを以下のように設定します。
DataSetOperation は DatabaseOperation.CLEAN_INSERT をデフォルトで設定します。 前述の例では BaseData.xml に定義された全テーブルを消去し、 BaseData.xml に宣言されているすべての行を挿入してから各 @Testメソッドが呼び出されます。
afterTestOperations の一覧にオペレーションを追加します。
datasourceJndiName を設定してデータソースに関する情報を DBUnit に伝える必要があります。
<parameter name="datasourceJndiName" value="java:/seamdiscsDatasource"/>
<parameter name="datasourceJndiName" value="java:/seamdiscsDatasource"/>
<parameter name="database" value="MYSQL" />
<parameter name="database" value="MYSQL" />
<parameter name="binaryDir" value="images/" />
<parameter name="binaryDir" value="images/" />
datasourceJndiName を指定しない限り、 テスト実行の前に setDatabaseJndiName() を呼び出す必要があります。HSQL、MySQL のいずれも使用していない場合は、いくつかのメソッドを無効にする必要があります。詳細は DBUnitSeamTest の Javadoc を参照してください。
35.3.4. Seam メールの統合テスト リンクのコピーリンクがクリップボードにコピーされました!
警告
FacesRequest を作成します。invokeApplication フック内では、getRenderedMailMessage(viewId); を使ってメッセージを表示し、表示すべきメッセージの viewId を渡します。メソッドはテストを実行できる表示されたメッセージを返します。また、 標準 JSF のどのライフサイクルメソッドでも使用できます。
第36章 Seam ツール リンクのコピーリンクがクリップボードにコピーされました!
36.1. jBPM デザイナとビューア リンクのコピーリンクがクリップボードにコピーされました!
36.1.1. ビジネスプロセスデザイナ リンクのコピーリンクがクリップボードにコピーされました!
36.1.2. ページフロービューア リンクのコピーリンクがクリップボードにコピーされました!
第37章 依存性 リンクのコピーリンクがクリップボードにコピーされました!
37.1. Java Development Kit (JDK) の依存性 リンクのコピーリンクがクリップボードにコピーされました!
37.1.1. Sun の JDK 6 に関する注意点 リンクのコピーリンクがクリップボードにコピーされました!
-Dsun.lang.ClassLoader.allowArraySyntax=true
37.2. プロジェクトの依存性 リンクのコピーリンクがクリップボードにコピーされました!
EAR タイプの依存性は、 ご使用のアプリケーションの EAR ファイルの /lib ディレクトリにそのライブラリを含ませます。 WAR タイプの依存性には、 ご使用のアプリケーションの WAR ファイルの /WEB-INF/lib ディレクトリにそのライブラリを含ませます。 それぞれの依存性のスコープは all、 runtime、 provided のいずれかです (JBoss AS 4.2 または 5.0 により)。
/build に格納されている Maven POM より生成する /dependency-report.txt に記載されています。 ant dependencyReport を実行するとこのファイルを生成できます。
37.2.1. Core リンクのコピーリンクがクリップボードにコピーされました!
|
名前
|
スコープ
|
タイプ
|
注記
|
|---|---|---|---|
jboss-seam.jar
|
all
| EAR
|
コアの Seam ライブラリで常に必要です。
|
jboss-seam-debug.jar
|
runtime
| WAR
|
開発時 Seam のデバッグ機能を有効にする場合に含めます。
|
jboss-seam-ioc.jar
|
runtime
| WAR
|
Spring と Seam を併用する場合に必要です。
|
jboss-seam-pdf.jar
|
runtime
| WAR
|
Seam の PDF 機能を使用する場合に必要です。
|
jboss-seam-excel.jar
|
runtime
| WAR
|
Seam の Microsoft® Excel® 機能を使用する場合に必要です。
|
jboss-seam-remoting.jar
|
runtime
| WAR
|
Seam Remoting を使用する場合に必要です。
|
jboss-seam-ui.jar
|
runtime
| WAR
|
Seam JavaServer Faces (JSF) のコントロールを使用する場合に必要です。
|
jsf-api.jar
|
provided
|
JSF API です。
| |
jsf-impl.jar
|
provided
|
JSF リファレンス実装です。
| |
jsf-facelets.jar
|
runtime
| WAR
|
Facelets です。
|
urlrewritefilter.jar
|
runtime
| WAR
|
URL Rewrite ライブラリです。
|
quartz.jar
|
runtime
| EAR
|
Seam の非同期機能で Quartz を使用する場合に必要です。
|
37.2.2. RichFaces リンクのコピーリンクがクリップボードにコピーされました!
|
名前
|
スコープ
|
タイプ
|
注記
|
|---|---|---|---|
richfaces-api.jar
|
all
| EAR
|
RichFaces を使用する場合に必要です。 ツリーの作成などアプリケーションからの使用を可能にする API クラスを提供します。
|
richfaces-impl.jar
|
runtime
| WAR
|
RichFaces を使用する場合に必要です。
|
richfaces-ui.jar
|
runtime
| WAR
|
RichFaces を使用する場合に必要です。 全 UI コンポーネントを提供します。
|
37.2.3. Seam Mail リンクのコピーリンクがクリップボードにコピーされました!
|
名前
|
スコープ
|
タイプ
|
注記
|
|---|---|---|---|
activation.jar
|
runtime
| EAR
|
添付のサポートに必要です。
|
mail.jar
|
runtime
| EAR
|
メール送信サポートに必要です。
|
mail-ra.jar
|
compile only
|
メール受信サポートに必要です。
| |
jboss-seam-mail.jar
|
runtime
| WAR
|
Seam Mail です。
|
37.2.4. Seam PDF リンクのコピーリンクがクリップボードにコピーされました!
|
名前
|
タイプ
|
スコープ
|
注記
|
|---|---|---|---|
itext.jar
|
runtime
| WAR
|
PDF ライブラリです。
|
jfreechart.jar
|
runtime
| WAR
|
チャートライブラリです。
|
jcommon.jar
|
runtime
| WAR
|
JFreeChart で必要です。
|
jboss-seam-pdf.jar
|
runtime
| WAR
|
Seam PDF のコアライブラリです。
|
37.2.5. Seam Microsoft®Excel® リンクのコピーリンクがクリップボードにコピーされました!
|
名前
|
タイプ
|
スコープ
|
注記
|
|---|---|---|---|
jxl.jar
|
runtime
| WAR
|
JExcelAPI ライブラリです。
|
jboss-seam-excel.jar
|
runtime
| WAR
|
Seam Microsoft® Excel® のコアライブラリです。
|
37.2.6. JBoss Rules リンクのコピーリンクがクリップボードにコピーされました!
drools/lib ディレクトリにあります。
|
名前
|
スコープ
|
タイプ
|
注記
|
|---|---|---|---|
antlr-runtime.jar
|
runtime
| EAR
|
ANTLR ランタイムライブラリです。
|
core.jar
|
runtime
| EAR
|
Eclipse JDT です。
|
drools-api.jar
|
runtime
| EAR | |
drools-compiler.jar
|
runtime
| EAR
| |
drools-core.jar
|
runtime
| EAR
| |
drools-decisiontables.jar
|
runtime
| EAR | |
drools-templates.jar
|
runtime
| EAR | |
janino.jar
|
runtime
| EAR
| |
mvel2.jar
|
runtime
| EAR
|
37.2.7. JBPM リンクのコピーリンクがクリップボードにコピーされました!
|
名前
|
スコープ
|
タイプ
|
注記
|
|---|---|---|---|
jbpm-jpdl.jar
|
runtime
| EAR
|
37.2.8. GWT リンクのコピーリンクがクリップボードにコピーされました!
|
名前
|
スコープ
|
タイプ
|
注記
|
|---|---|---|---|
gwt-servlet.jar
|
runtime
| WAR
|
GWT Servlet ライブラリです。
|
37.2.9. Spring リンクのコピーリンクがクリップボードにコピーされました!
|
名前
|
スコープ
|
タイプ
|
注記
|
|---|---|---|---|
spring.jar
|
runtime
| EAR
|
Spring Framework ライブラリです。
|
37.2.10. Groovy リンクのコピーリンクがクリップボードにコピーされました!
|
名前
|
スコープ
|
タイプ
|
注記
|
|---|---|---|---|
groovy-all.jar
|
runtime
| EAR
|
Groovy のライブラリです。
|
付録A 改訂履歴 リンクのコピーリンクがクリップボードにコピーされました!
| 改訂履歴 | |||
|---|---|---|---|
| 改訂 5.1.2-2.400 | 2013-10-31 | ||
| |||
| 改訂 5.1.2-2 | 2012-07-18 | ||
| |||
| 改訂 5.1.2-100 | Thu 8 December 2011 | ||
| |||








