はじめに
RSS(RDF Site Summary)とは、その名の通り、サイトのサマリ情報を配信するためのデータ記述フォーマットです。皆さんも、さまざまなサイトで「RSS」と書かれたというアイコンを見かけることがあるでしょう。これは、そのサイトでRSS情報を配信しているということを表すものです。昨今はやりのブログでは、標準でRSSに対応しているものも多くなってきましたから、知らず知らずのうちにRSSを利用していたという方も多いかもしれません。
RSSを利用することで、エンドユーザは自分が興味を持ったサイトをいちいち巡回する必要はありません。「RSSリーダ」と呼ばれる専用のクライアントアプリケーションにRSSの配信元を登録しておくだけで良いのです。すると、RSSリーダがあらかじめ設定した間隔でそれぞれのサイトからRSS文書(「RSSフィード」とも言います)を取得してくれますので、ユーザはその収集結果をひとところで確認できます。
また、RSSによって恩恵を受けるのはこうしたエンドユーザばかりではありません。自分で独自のサイトを立ち上げている方ならば、自サイトに関係するサイトが提供するRSSフィードをインポートしても良いでしょう。たとえば、自サイトでIT関係の話題を扱っているならば、@ITや(手前味噌ですが)著者サイト「サーバサイド技術の学び舎 - WINGS」が提供するRSSフィードを取り込んでおけば、常に最新の公開記事を自サイトで紹介することができます。
本稿では、このようにWebサイト上で利用可能なRSSリーダを紹介します。出力レイアウトはテンプレートで指定できますので、サイトのデザインに応じて簡単に見栄えをカスタマイズできるのが特長です。
必要な環境
本稿で紹介するフォルダシステムは、JSP2.0&サーブレット2.4環境で動作するカスタムタグです。利用するにあたっては、以下のソフトウェアが最低限必要となります。これらソフトウェアのインストール方法については、著者サイト「サーバサイド技術の学び舎」より「サーバサイド環境構築設定」を参照してください。
- J2SE 5.0_02
- JSP&サーブレットコンテナ(Tomcat 5.5.7で確認済)
- Rss4J
サンプルコードは「.war」形式で提供しています。記事上部のリンクからダウンロードできる「CZ_RssReader.war」を「%CATALINA_HOME%/webapps」フォルダ配下に配置し、コンテナを再起動することで自動的に展開されます。
また、サンプルフォルダ「/CZ_RssReader」の直下には、カスタムタグを実際に試すための「sample.jsp」が含まれていますので、以下のURLから起動し、コードが正常に動作していることを確認してください。
http://localhost:8080/CZ_RssReader/sample.jsp
Rss4Jについては、ダウンロードファイルに既に含まれていますので、サンプルをそのまま利用する場合には改めてインストールする必要はありません。
ファイル構造
先述したように、本稿で紹介するRssReaderはJSP2.0&サーブレット2.4環境で動作するカスタムタグです。まずは、ダウンロードファイル内のファイル構造を示しておきます(赤字のファイルは、他のアプリケーションで利用する場合に必要なファイルであることを表します)。
<RssReader>要素の利用方法
カスタムタグ<RssReader>
要素で利用可能な属性は、以下の通りです。
属性 | フラグメント | 概要 |
url | × | 取得したいRSSフィードのURL |
header | ○ | ヘッダテンプレート |
body | ○ | 本体テンプレート |
footer | ○ | フッタテンプレート |
また、それぞれのテンプレート(フラグメント)内では、以下のページ属性を利用可能です。ページ属性は、${属性名}
の形式で参照可能です。
テンプレート | 属性名 | 概要 |
ヘッダ | channet_title | チャネルのタイトル |
本体 | title | 記事タイトル |
link | 記事のURL | |
description | 記事の説明文 | |
フッタ | なし |
以上に基づいて、具体的なJSPページの記述例を見てみることにしましょう。
<%@ page contentType="text/html;charset=Windows-31J" %> <%@ taglib prefix="cz" uri="http://www.wings.msn.to/CodeZineTagLibs-1.0" %> <cz:RssReader url="http://www.wings.msn.to/redirect.php/-/A-12/"> <jsp:attribute name="header"> <table bordercolor="#000000" cellspacing="1" bordercolordark="#ffffff" cellpadding="5" bordercolorlight="#000000" border="1"> <tr> <td bgcolor="#FFffEE"> <h2>${channel_title}</h2> <ol> </jsp:attribute> <jsp:attribute name="body"> <li><a href="${link}" style="color:#220055">${title}</a></li> </jsp:attribute> <jsp:attribute name="footer"> </td> </tr> </table> </jsp:attribute> </cz:RssReader>
ポイントとなるのは、以下の2点です。
@taglib
ディレクティヴでタグライブラリを登録する- フラグメントは
<jsp:attribute>
要素で記述する
@taglib
ディレクティヴでタグライブラリの登録を行う必要があります。この際、uri
属性の値は固定ですが、prefix
属性は自由に決めることができます。ただし、prefix
属性はコード中の要素プレフィックス(<xx:~>
の部分)と対応関係にある必要がありますので、注意してください。<RssReader>
要素では、フラグメントを利用して、ヘッダ、本体、フッタという3つのテンプレートをJSPページから指定できるようにしています。フラグメントにテンプレートを引き渡すには、<RssReader>
要素の配下に<jsp:attribute>
要素を記述します。<jsp:attribute>
要素の一般的な構文は以下の通りです。<jsp:attribute name="属性名">テンプレート本体</jsp:attribute>
タグハンドラクラスRssReaderTagの骨格
<RssReader>
要素の使い方を理解したところで、<RssReader>
要素の挙動を定義するタグハンドラクラスRssReaderTag
の中身を覗いてみることにしましょう。まずはタグハンドラクラスの基本的な骨格を理解します。
public class RssReaderTag extends SimpleTagSupport { private String url; private JspFragment header; private JspFragment body; private JspFragment footer; public void doTag() throws JspException, IOException { ...中略... } public void setUrl(String url){this.url=url;} public void setHeader(JspFragment header){this.header=header;} public void setBody(JspFragment body){this.body=body;} public void setFooter(JspFragment footer){this.footer=footer;} }
タグハンドラクラスで最低限必要なポイントは、以下の3点です。
SimpleTagSupport
クラスを継承する- タグの処理を規定するのは
doTag
メソッドの役割 - 属性はアクセサメソッドとして定義する
SimpleTagSupport
クラスはカスタムタグの基本的な機能を提供するクラスです。タグハンドラクラスを定義するには、SimpleTagSupport
クラスを継承し、これに対して必要なロジックを追加する必要があります。なお、定義するタグの種類によっては、SimpleTagSupport
クラスの代わりに、TagSupport
、BodyTagSupport
クラスを利用する場合もあります。SimpleTagSupport
派生クラスにおいて、タグの挙動を規定するのはdoTag
メソッドの役割です。doTag
メソッドに、必要な一連の処理を記述します。url
、header
、body
、footer
という4つの属性を公開したいので、それぞれ対応するsetUrl
、setHeader
、setBody
、setFooter
メソッドを定義しています。なお、タグハンドラクラスを利用する場合には、デプロイメントディスクリプタ(web.xml)、タグライブラリディスクリプタ(myTag.tld)に適切な設定を施しておく必要があります。本稿では割愛しますが、詳細はダウンロードファイルに含まれる該当のファイルを参照してください。
Rss4JによるRSSフィードの読み込み
タグハンドラクラスの骨格が理解できたところで、次にdoTag
メソッドの中身、url
属性で指定されたRSSフィードを読み込み、指定されたテンプレートに基づいて出力するためのロジックを概観してみることにしましょう。以下は、doTag
メソッドの中身です。
PageContext pageContext=(PageContext)this.getJspContext(); URL rss=new URL(this.url); RssDocument doc=null; try { doc = RssParser.parseRss(rss.openConnection().getInputStream()); } catch (RssParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Enumeration objEnm=doc.channels(); while(objEnm.hasMoreElements()){ RssChannel channel=(RssChannel)objEnm.nextElement(); pageContext.setAttribute("channel_title", channel.getChannelTitle()); header.invoke(null); Enumeration items=channel.items(); while(items.hasMoreElements()){ RssChannelItem item=(RssChannelItem)items.nextElement(); pageContext.setAttribute("title",item.getItemTitle()); pageContext.setAttribute("link",item.getItemLink()); pageContext.setAttribute("description", item.getItemDescription()); body.invoke(null); } footer.invoke(null); }
Rss4Jの中核を担うのはRssParser
クラスです。RssParser#parseRss
メソッドに対して、RSSフィードを表す入力ストリームを引き渡すことでRSSフィードが解析され、解析済みのRSS情報がRssDocument
オブジェクトとして返されます。
RssDocument
オブジェクトは、配下にチャネル情報や個々の記事情報を含むオブジェクトツリーとなっていますので、あとは対応するメソッドを辿っていくだけで必要な情報を直感的に取得できるのが特長です。
取り出した情報は、PageContext#setAttribute
メソッドでページ属性に登録した上で、JspFragment#invole
メソッドで対応するテンプレート(フラグメント)を呼び出してください。ここでは、チャネル情報を取り出す都度にheader
テンプレートを、チャネル配下のアイテム情報を取り出す度にbody
テンプレートを、そして、アイテム情報を出力し終わった直後にfooter
テンプレートを、それぞれ出力しています。
まとめ
以上、JSP&サーブレットアプリケーションで利用可能な<RssReader>
要素を紹介してみました。本稿ではまずはRSSフィードでよく利用する情報のみを出力可能にしていますが、もちろん、RSSフィードにはこの他にもさまざまな情報が含まれています。Rss4Jを使えばそれらの情報を簡単に取り出すことができるでしょう。
参考資料
- ChurchillObjects.com 『Rss4J』