2006年 4月 01日 土曜日
Shale Remoting と JSF カスタムコンポーネント - その2
さて、じゃあ実際どうやるのかっていうと。。。まず Shale Remoting がやることは基本的に、内部の PhaseListener がリソースへのリクエストを managed bean の deferred メソッド(ところで deferred method ってなんていうんだろう? 遅延メソッド?)へ delegate するってことです。だからユーザはリクエストを実際のサーバ内部用にプロパゲートしたり
とかいうコードを書く必要がなくなります。じゃあまずスタティックなリソースへのリクエストから:
これは超簡単。JSF のカスタムコンポーネントが複数集まったライブラリ jar の構造を思い浮かべてみてください。EJB jar みたいで、ejb-jar.xml の代わりに faces-config.xml と TLD ファイルが META-INF の下に入っているような感じです。スタティックなリソースは
たぶん META-INF/
resource-directory/yuta.js でしょう。これを取るには、コンポーネント中のレンダラーで↓みたくすればOK。
private static XhtmlHelper helper = new XhtmlHelper();
public void encodeEnd(FacesContext context, UIComponent component)
throws IOException {
ResponseWriter writer = context.getResponseWriter();
//shale remoting resource retrieval
helper.linkJavascript(context, component, writer,
Mechanism.CLASS_RESOURCE, "/META-INF/r-dir/yuta.js");
出力された HTML を見てみると context root なんかが結合されたパスになってます。このリクエストが来ると Shale が自動的にリソースをとってくれます。
次はダイナミックリソース。
ダイナミックリソースというと、servlet が GET/POST
リクエストでダイナミックな HTML を返すというのを思い浮かべますが、JSF のコンポーネントではおそらく Managed Bean のある特定のメソッドを使うのがいいと思います。
ダイナミックリソースの取得に Shale Remoting を使うにはレンダラ、faces-config.xml
、そしてリクエストを受け取る Managed Bean 三つのコーディングが必要です。
- faces-config.xml
まず Managed Bean の設定。リソース取得用の URL にnameというパラメタをつける例を
考えて見ます。URL?name=yutaみたいな場合ですね。
<managed-bean>
<managed-bean-name>c_request_handler</managed-bean-name>
<managed-bean-class>クラスバス</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>name</property-name>
<value>#{param.name}</value>
</managed-property>
</managed-bean>
レンダラー
private static XhtmlHelper helper=new XhtmlHelper();
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException {
ResponseWriter writer = context.getResponseWriter();
// コールバック用のストリングを作ります
// "c_request_handler というのは、上のfaces-config中で指定した managed bean
// の名前です。
String callBackString = helper.mapResourceId(context,
Mechanism.DYNAMIC_RESOURCE,
"/c_request_handler/handleRequestMethod");
// この後、callBackString をjavascript で例えばボタンの onClick で別の
// function() を呼んでその中で XmlHttpRequest で送るための URL として
// 指定したりします
Managed Bean
Managed Bean 中では Shale Remoting だからといって特別なことはないんですけど、
プロパティとしてname を持ってるんだから、
setName()、
getName() は必要です。そしてレンダラー中で書いたメソッド
handleRequestMethod()で
getName()とすれば
http://ほにゃらら/ほげほげ/handleRequestMethod?name=yoshida
なんていうリクエストがきたら Shale が自動的に値を返してくれます。
もうひとつ。 Managed Bean 中でもぜひ ResponseFactory を使ってください。↓
private static ResponseFactory factory = new ResponseFactory();
.........
public void handleRequestMethod() {
FacesContext context = FacesContext.getCurrentInstance();
..........
ResponseWriter writer = factory.getResponseWriter(context, "text/html");
writer.startElement(.................);
..........
}
さて・・・PhaseListener をごりごり使うより数倍楽じゃありませんか?
一番いいのは、コンポーネントの作成が一つ一つ独立することだと思います。
みなさんも、ぜひお試しください。
Posted by yuta
( 4月 01日 2006年, 07:59:32 午後 PST )
Permalink