Wicketで始めるオブジェクト指向ウェブ開発

第7回 自作コンポーネントで再利用可能オブジェクトを作る

この記事を読むのに必要な時間:およそ 6.5 分

前回まででタイムラインの表示が完成しました。なんとかTwitterらしいものが表示できましたが,最新20件しか表示できないという欠点がありました。ここを改善するために,過去20件を表示できるようにするのが,今回の目的です。

しかしその目的の前に,前回作ったプログラムのもうひとつの欠点「アイコン画像の表示が遅い」という問題を解決しておきましょう。

サンプルプログラムの修正について

第2回で配布したサンプルプログラムから若干の変更が入っています。第2回でサンプルプログラムをダウンロードした方は再度,次のリンクからダウンロードをお願いします。

また,現在のtwitter4jに存在するバグ対応のため,前回までのサンプルプログラムにも若干の修正を加えました。詳しくは,サンプルプログラムのjp.gihyo.wicket.TwitterClientクラスを参照してください。

タグの属性を操作する

前回のプログラムで画像表示が遅いのは,画像表示のためにImageコンポーネントを使用したことが原因です。Imageコンポーネントは,プログラム的に動的に作成する画像を表示するために用意されたもので,Twitterアイコン画像のような固定画像表示には向いていません。理由は2点あります。

  • Imageを使うとプログラムが動いてしまう。画像への直接のリンクであれば,レスポンスはWicketのプログラムを必要としません。
  • Imageは画像のURLを動的に生成する。Imageは同じ画像であってもWebResourceごとに個別のURLを生成します。ブラウザは同じ画像のために複数のアクセスを必要とします。

前回のプログラムで表示したページのソースを見てみると,同じユーザのステータスであっても,<img>タグのsrc属性が毎回異なっていることが確認できます。それぞれがプログラムで作成したWebResourceへのリンクです。ブラウザはすべてのアイコン画像に対して個別のリクエストを投げるため,ブラウザにとっても,サーバにとっても負荷が高くなります。

ブラウザが効率良く動作するように変更するならば,<img>タグのsrc属性に,Twitterアイコン画像へのURLを直接埋め込むのが良いでしょう。そのために使うのが,ビヘイビアです。

ビヘイビアはコンポーネントのプラグイン

Wicketのコンポーネントの大きな目的は,HTMLタグを変更・生成することです。ComponentクラスにあるonComponentTag()メソッドがタグ生成の役割を担っており,オーバーライドすればタグ生成方法を細かく制御することができます。

しかし属性変更のようなちょっとしたタグ変更のためにいちいちコンポーネントのサブクラスを作っていたのでは,さすがにサブクラスが増えすぎてしまいます。また,同じような変更をするだけなのに,クラスが異なるためにいちいち別のサブクラスを作らなくてはいけません。

そのために,Wicketにはコンポーネントのタグ生成に介入するためのプラグイン的機構があります。それが「ビヘイビア」です。

ビヘイビアをコンポーネントに追加することで,コンポーネントのタグ生成処理に介入することができます。コンポーネントは「ビヘイビアが登録された直後」⁠タグ生成処理実行直後」⁠タグ出力前」⁠タグ出力後」といったタイミングで,ビヘイビアに処理を委譲します。多くのコンポーネントに共通の操作をビヘイビアとしてまとめておくことで,コンポーネント操作をオブジェクトとして再利用可能になります。

しかも,ビヘイビアはコンポーネントに対していくつでも登録することができます。継承ではひとつの機能しか追加することができませんが,ビヘイビアにすることで,複数個の機能をまとめてコンポーネントに追加できるのです。

SimpleAttributeModifierビヘイビアで属性を変更する

ビヘイビアはコンポーネントへの操作をオブジェクト化して再利用可能としたものです。Wicketはビヘイビアとして,多くのクラスをあらかじめ提供しています。その中に「タグ属性を変更するビヘイビア」であるSimpleAttributeModifierがあります。

サンプルプログラムのjp.gihyo.wicket.page.paging.PagingTimelineを見てください。このプログラムは,前回までに作ったMyTimelineクラスを改変したものです。プログラムはほぼ同じですが,ところどころ変更しています。このクラスに,次のような箇所があります。

リスト1 SimpleAttributeModifierでsrc属性を変更する例

//Imageコンポーネントではなく,<img>タグのsrc属性を変更する形式に変更
WebMarkupContainer userImage = new WebMarkupContainer("imageLink");
userImage.add(new SimpleAttributeModifier("src", status.getUser().getProfileImageURL().toString()));

いままでImageコンポーネントを使っていたところが,WebMarkupContainerクラスに変わっています。WebMarkupContainerクラスは,タグをWicketコンポーネントとして扱えるようにするだけのコンポーネントで,それ自体には機能はありません。HTMLファイルに記述されているタグがそのまま出力されます。ここでWebMarkupContainerを使うことで,<img>タグにビヘイビアを追加できるようにしているのです。

SimpleAttributeModifierのコンストラクタに属性名と文字列を渡すことで,タグの属性を変更することができます。属性がHTMLに存在しない場合は属性が追加されます。属性名としてsrcを,新しい属性値としてtwitter4jを使って取り出したProfileImageURLを文字列化したものを渡しています。これにより,タグのsrc属性を変更することができます。

サンプルプログラムを起動し,http://localhost:8080/wicket-sample/pagingにアクセスすると,前よりも画像が速く表示できることが体感できます。HTMLソースを見れば,<img>タグのsrc属性値がTwitterが使っている画像URLになっていることが確認できます。

もっとフレキシブルな属性変更を行う

多くの場合はSimpleAttributeModifierで対応可能ですが,もっと動的に,状況により設定される属性値がかわるようなケースに対応するには,モデルを介して属性値を指定したいところです。

そのためには,SimpleAttributeModifierクラスのスーパークラスであるAttributeModifierクラスを使うとよいでしょう。属性値としてモデルを使用することができます。

また,SimpleAttributeModifierやAttributeModifierは属性値を常に置き換えますが,置き換えるのではなく追加したい場合もあります。その場合には,AttributeModifierクラスを使用してください。

著者プロフィール

矢野勉(やのつとむ)

フリーランスのプログラマ。Wicket-ja主催。

ウェブ・アプリケーションの開発を中心にさまざまな案件に関わってきました。現在はWicketによる開発を支援しています。

URLhttp://d.hatena.ne.jp/t_yano/

著書

コメント

コメントの記入