JBoss Seamのサンプルアプリを試す。その2
昨日に続きhttp://docs.jboss.com/seam/reference/en/html/tutorial.html#d0e493を見ていきます。
4. The web deployment description: web.xml
web.xmlは3.1. Integrating Seam with JSF and your servlet containerにもありますが、
<!-- Seam --> <listener> <listener-class>org.jboss.seam.servlet.SeamListener</listener-class> </listener>
は、Seamアプリケーションには必須だそうです。
残りもSeamアプリケーションでは完全に同じだそうです。
5. The JSF configration: faces-config.xml
Seamアプリケーションはプレゼンテーション層にJSFを使うのでfaces-config.xmlも必須です。
サンプルアプリケーションのregistrationのjsf-config.xml(faces-config.xmlの間違いだと思う。)には一つだけのナビゲーションルールがあるだけです。ManagedBeanの宣言がないことに注目して下さい(Seamアプリケーションには必要ありません)。ManagedBeanはSeamコンポーネントです。Seamアプリケーションに於いてはjsf-config.xml(faces-config.xmlの間違いだと思う。)はJSFのoutcomeにあるアクションの実行結果と表示ページのマッピングによるページ遷移を指定するためだけに使われます。
事実、基本的な記述子をセットしてもSeamアプリケーションに新しい機能を追加してもXMLにページ遷移を書くだけです。SeamはXMLに記述されたプロセスフローと設定データのみからビューを作成します。
6. The view: register.jsp and registered.jsp
SeamアプリケーションのビューページはJSFのサポートする技術を使って実装されています。ここでは開発者に最も馴染みのあるJSPを使っていますしここでは最低限必要とされるものです。(アドバイスとしてはFaceletを使った方が良い)。
7. The EAR deployment descriptor: application.xml
最後に、SeamアプリケーションはEARとしてデプロイされます、デプロイメントディスクリプタも必要です。
このデプロイメントディスクリプタはエンタープライズアーカイブもモジュールとWebアプリケーションのContextRootを/seam-registrationへリンクします。
以上でアプリケーションの全てのファイルを見終わりました。
How it works
-
- フォームが送信されたとき、JSFはSeamへuserと言う名前解決を求めます。
- その名前に値が結びつけられていないときは、Seamはuserコンポーネントをインスタンス化し、Seamのセッションコンテキストを保存した後にUser EntiryBeanのインスタンスをJSFへ返します。
- JSFはUser EntityBeanのプロパティとフォームに入力された値を結び付けます
- 次にJSFはSeamへregisterと言う名前解決を求めます。
- SeamはRegisterActionステートレスセッションビーンをステートレスコンテキスト内に見つけJSFへ返します。
- JSFはActionListenerメソッドのregister()を実行します。
- Seamはメソッドコールに割り込みHibernate ValidatorにSessionBeanのインスタンス(再帰的にUser EntityBeanも)を検査を依頼する前にセッションコンテキストと現在のFacesContextインスタンスからUser EntityBeanに注入にます。
- 状態(値)に問題がないなら,そのまま実行されregister()メソッドが呼ばれます。
- 問題があれば、Seamはnullをoutcomeに返し、JSFページを再表示します。
- JSFが次のJSPページを表示しSeamにuserと言う名前の解決を求めると、Seamセッションスコープから返るUser EntityBeanのプロパティの値を使います。
JBoss Seamのサンプルアプリを試す。その1
http://docs.jboss.com/seam/reference/en/html/index.htmlを読み始めました。以下は拙い日本語訳です。間違いがあればご指摘下さい。ダウンロードしたSeam一式の中にLGPLとあったので日本語訳していますが、拙いようであればご指摘下さい(Sales宛--しかcontact先はなかった--にE-Mailを送りましたが返事はありません)。
http://docs.jboss.com/seam/reference/en/html/tutorial.html
まずはregistrationサンプルを動かしてみます。
JBoss SeamのサンプルをEclipse上で動かす。にてCVSから持って来たソースをそのまま使います。
- Eclipse上でjboss-seamのbuild.xmlを右クリック Run As-Ant Build
- examples/registrationのbuild.xmlを右クリック Run As-Ant Build
- Debug-JBoss Seam(4.0.3 SP1をdefaultで)にてJBossを起動する。
- http://localhost:8080/seam-registration/register.jsf へアクセス。
で、問題なく動作します。JBoss_Home/server/default/deploy/jboss-seam-registration.earをJBossのDBをPostgreSQL 8.0へ変更する。で作成したJBoss_Home/server/postgres/deploy/へコピーしてJBoss_Home/bin/run.bat -c postgresで再起動しても問題なく動作します。もちろんPostgresのDBにはusersと言うtableが作成されていました。
サンプルアプリケーションregistrationを詳しく見てみます。/examples/registrationの中にあるファイルは以下のものだけです。
プレゼンテーション部分のjspファイルが2つ、SessionBeanのinterfaceとBean、EntityBeanと残りは設定ファイルです。
1. The entity bean: User.java
プロパティに
String username;
String password;
String name;
とこれらのsetter,getterと引数なしのと引数ありのコンストラクタとannotationだけです。
AnnotationとSeam特有部分
-
- @EntityはこのクラスがEJB3.0(The Java Community Process(SM) Program - communityprocess - prのJava Persistence API)で定義されたEntityBeanクラスであるとの宣言です。
- @Name("user")はSeamコンポーネントが必要とするコンポーネント名を定義するものでSeamアプリケーション内で一意でないといけません。JSFがSeamにSeamコンポーネントと同じ名前を使ってコンテキスト変数を解決しようとした場合現在はコンテキスト変数は定義(Null)されていません。Seamはコンポーネントをインスタンス化し新しいインスタンスをコンテキスト変数へバインドします。この場合JSFがuserと名づけた変数を扱う最初にSeamはUserをインスタンス化します。
- @Scope(SESSION)Seamがコンポーネントをインスタンス化したときにはインスタンス化されたコンポーネントはコンポーネントのディフォルトコンテキストにバインドされます。ディフォルトコンテキストは@Scopeで定義されます。UserBeanはセッションスコープのコンポーネントです。
- @TableEJB3.0で定義されたAnnotationでUserクラスはusersテーブルにマップされます。
- クラスのプロパティname,password,usernameはEntityBeanの属性です。全ての永続属性はアクセッサメソッドを定義する必要があります。JSFがレンダーレスポンスやアップデートモデルバリューフェイズでこのコンポーネントを使うときに必要になります。
- 引数なしのコンストラクタはEJB仕様とSeamの両者が必要とします。
- @NotNull,@LengthはHibernateのValidatorフレームワークの一部です。SeamはHibernateのValidatorを進化させデータのValidationに使うことが出来ます(Hibernateを永続化に使ってなくても)
- @IdEJB3.0で定義されたAnnotationでEntityBeanのプライマリーキーを定義します。
このファイルの最も大切なものは@Name,@Scope Annotationです。このAnnotationがこのクラスをSeamのコンポーネントとして成立させます。
以降で述べるようにUserクラスのプロパティはJSFがコンポーネントに直接結合されJSFがアップデートモデルバリューフェイズの間存在させます。JSPページとEntityBeanドメインモデル間でデータをコピーするような退屈なコードを書く必要はありません。
どちらにしてもEntityBeanでトランザクション管理やデータベースへのアクセスを行うべきではない。このコンポーネントはJSFのAction Listerとしては使うことが出来ません。そのためにはSessionBeanが必要です。
2. The stateless session bean class: RegisterAction.java
Seamアプリケーションで最も使うのはSessionBeanをJSFのAction Listerとしてです(代わりにJavaBeanも使えます)。
アプリケーション内でJSFのActionとSessionBeanのメソッドは正確に対応しています。ここではステートレスSessionBeanを使い、UserBeanにより起こされたActionと全ての状態は結び付けられています。
このサンプルアプリケーションでは一番興味あるコードです。
-
- @StatelessはこのクラスがEJB3.0(The Java Community Process(SM) Program - communityprocess - prのEJB 3.0 Simplified API)で定義されたステートレスSessionBeanとしてのクラスのAnnotationです。
- @Scope,@Nameは上記と同じです。
- @Interceptor(SeamInterceptor.class)はSeamコンポーネントとしてのSessionBeanには全てSeamInterceptorをEJB Interceptorとしなければなりません。
- @InはSeamによって注入されたBean属性だと明らかにするものでこの場合user(インスタンス変数名)と名付けられたコンテキスト変数から注入された属性です。
- @ValidはHibernate Validatorから提供されたもので関連するオブジェクトに再帰的にValidationを行います。
- @PersistenceContextはEJB3のEntityManagerを注入するのにつかわれるEJBのAnnotationです。
- SeamはSeamやjBPMコンテキストオブジェクトが注入された、さまざまなJFSが使えます。Seamに注入されたFacesContextインスタンスを得るためにfacesContextインスタンスを@Inと一緒に使っいます。
- @IfInvalidはAction Listenerメソッドが実行される前にHibernate Validatorを使いコンポーネントの状態をValidateするようSeamに伝えます。
- 通常のEJB3の EntityManager APIはAction Listerメソッドを使ってデータベースと協調し、JSFへ出力します。これはSessionBeanですが、registerメソッドが呼ばれてから自動的にトランザクションが開始され完了するとCommitされます。
今回@Scopeが明示的に示されていませんが、その場合はSeamコンポーネントはデフォルトのスコープを持ちます。ステートレスSessionBeanの場合はデフォルトのスコープはステートレスコンテキストです。実際全てのステートレスSessionBeanはステートレスコンテキストに属します。
このアプリケーションではSessionBean Action Listenerはビジネスと永続性のロジックを実行します。もう少し複雑なアプリケーションでは永続性ロジックはデータアクセスコンポーネントに専念するような階層にリファクタリングする必要があるでしょう。実際はそのようにされるでしょう。ただSeamは何層にも及ぶアプリケーションをあなたに課する訳ではないことをお伝えしたいのです。
更に、SessionBeanはWebリクエスト(例えばFacesContextオブジェクト)とトランザクションリソース(EntityManager)を合わせたコンテキストへ同時にアクセス出来ます。これは従来のJ2EEアーキテクチャーを超えるものです。もしあなたが従来のJ2EE層が良いのであればSeamアプリケーションをそのように実装することも出来ます。しかし沢山のアプリケーションは単純に使い物にならないでしょう。
3. The session bean local interface: Register.java
SessionBeanはlocal interfaceを必要とします。
Javaのコードは以上でおしまいです。ここからはDeployment Descriptorsです。
JBoss SeamのサンプルをEclipse上で動かす-その2
昨日のJBoss 4.0.3.SP1のhibernate3.jarのバグの問題にトライする。
- EclipseのCVSにリポジトリを下記にて追加
- Host:cvs.sourceforge.net
- Repositry Path:/cvsroot/hibernate
- User:anonymous
- VersionsからHibernate3/Hibernate3 v31rc2を選びチェックアウト
- Class Pathにjunit.jar,antlr-2.7.5H3.jarを追加し、build.
- JBoss_Home/server/default/libのhibernate3.jarを上書きする。
以上で問題なく動きました。詳細はこれから勉強します。
JBoss SeamのサンプルをEclipse上で動かす。
JBoss Seam is an application framework for Java EE 5. Seam unifies the component models of JSF and EJB 3.0, providing a streamlined programming model for web-based enterprise applications.
Java EE 5を使ったフレームワークで、JSFとEJB 3.0を統合するコンポーネントモデルでWebベースのエンタープライズアプリ開発に合理的なプログラミングモデルを提供する---のだそうです。
又、デモページには
Creating powerful enterprise applications has never been this easy. Seam combines Enterprise JavaBeans 3.0 components with rich component-based user interfaces built using JavaServer Faces, and lets developers build more robust applications more quickly and with astonishingly little code. Seam helps eliminate a whole class of bugs that plague web development by introducing the concept of declarative application state management.
強力なエンタープライズアプリを作るのは容易じゃない。SeamはEJB 3.0とJSFで作成された強力なコンポーネントベースのユーザインターフェイスを統合し、開発者に堅牢なアプリを素早くたまげるくらい少ないコードで作成させるものです。アプリの状態管理を記述するという考え方を持ち込んだめんどいWeb開発の全部のクラスのバグを無くするのを手助けしてくれる。と、あります。
ちょうどフロントはStrutsからJSFかな〜と思い始めていたし、バックはEJB3.0で決まりか〜と思っていたのでちょっとかじってみることにした。
JBoss SeamのサンプルアプリbookingをEclise上で動かす方法がhttp://wiki.jboss.org/wiki/Wiki.jsp?page=UseJBossEclipseIDEToDoJBossSeamsBookingExampleにあるそうなので、トライしてみた。
- JDK 1.5が必要-当然Eclipseは3.1.1
- JBoss IDE - JBoss Communityも1.5系(RC1を使用)
- JBoss ASは4.0.3をインストーラを使ってejb3でインストール
だ、そうです。
上記の通りにやったのだが、17あたりのpropertyファイルが見つけられなかったりしたので、ここにあるFlushUnderstanding middlewareの通りにやると動いた。
しかし、ログイン後Hotelのデータが空っぽでそれ以上進めません。http://www.jboss.com/index.html?module=bb&op=viewtopic&t=71903にあるようにJBoss 4.0.3SP1はHibernate3のスナップショットなのでバグがあり、import.sqlがうまく動作しないようです。解決策はHibernate3のCVSからソースを落してBuildしてhibernate3.jarを入れ替えろとのことです。
参考:id:neverbird:20051107