2010年8月28日土曜日

JavaでRSSを作成(ROME利用)

すごく今さらなトピックで申し訳ないんですが。
ServletのWEBシステムで「RSS配信をしたい」と言われたので対応しようと調べてみたんですが、Readerを作るサンプルは多いのに、生成する方については日本語のページがあまりなかったようなので、誰かの役に立てば幸いとばかりに記載しておきます。

JavaでRSSを生成するためのライブラリはいくつかあるようですが、どれも生きてるのか怪しそうなのでsunのパッケージに入っていてバージョンも「1.0」に到達している「ROME」を利用しました。
必要なライブラリは、rome.jarと、jdom.jarの2つです。

まずは以下からrome.jarをダウンロード。
https://rome.dev.java.net/

2010年8月現在の画面ではこんな感じ。


もう一つ、jdomが必要なのでこれもダウンロード。
必ず本家サイトからダウンロードしましょう

ボクは横着者なので「jdom.jar ダウンロード」でググって表示された、とあるプロジェクトが2次配布しているjarをダウンロードして動かそうとしたら、
「Exception in thread "main" java.lang.NoClassDefFoundError: org/jdom/Content」
と出てしまってなかなか先に進めなかった、という恥ずかしい過ちを犯しました。
(ROME1.0で内部的に利用しているContentクラスは、古いバージョンのjdom.jarには入っていない様子)

jdomを本家からダウンロード。


ディレクトリのリストが表示されたら最新バージョンのzipのリンクをクリック。


無事落としたら、解凍。
解凍して出来るjdom/buildフォルダ内にお目当てのjdom.jarがいるはずですが、もしなかったら「jdom」直下にある「build.bat」を走らせればbuildフォルダ内に現れるはずです。

以上の2つにクラスパスを通します。
Eclipseだと

プロジェクト>プロパティ>Javaのビルドパス>外部jarの追加

で表示されるファイル選択ダイアログで、2つのjarを選択して追加すればOKです。

以下、サンプルソース。
ROMEだけで十分使えるけど、「新しいライブラリなんてよくわからないよ」という向上心が消え去ってしまったメンバーばかりのプロジェクトで何とか頑張っているアナタ、あなた、そして貴方のために、そんな人たちでもとりあえず使えるラッピングをプレゼント(笑)。

FeedCreator.java



package jp.boldweb.feed.core;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedOutput;

public class FeedCreator {
private String feedType;
private String title;
private String link;
private String description;
private List entries;

/**
* デフォルトコンストラクタ。「RSS 2.0」形式でFeedを生成します。
*/

public FeedCreator(){
this("rss_2.0");
}

/**
* コンストラクタ
* @param feedType フィードの形式
* "rss_1.0"
* "rss_2.0"
* "rss_0.9"
* "rss_0.92"
* "atom_1.0"
* "atom_0.3"
*/

public FeedCreator(String feedType){
this.feedType = feedType;
entries = new ArrayList();
}

/**
* フィードの形式を指定します。
* @param feedType
*/

public void setFeedType(String feedType){
this.feedType = feedType;
}

/**
* フィードのタイトルを指定します。
* @param title
*/

public void setFeedTitle(String title){
this.title = title;
}

/**
* 配信元サイトのURLを指定します。
* @param link
*/

public void setFeedLink(String link){
this.link = link;
}

/**
* フィードの概要を指定します。
* @param description
*/

public void setFeedDescription(String description){
this.description = description;
}

/**
* テキスト形式の詳細エントリーを指定します。
* @param title
* @param link
* @param value
* @param pubDate
*/

public void setTextEntry(String title, String link, String value, Date pubDate){
SyndEntry entry;
SyndContent description;

entry = new SyndEntryImpl();
entry.setTitle(title);
entry.setLink(link);
entry.setPublishedDate(pubDate);

description = new SyndContentImpl();
description.setType("text/plain");
description.setValue(value);

entry.setDescription(description);
entries.add(entry);
}

/**
* 指定された形式でフィードを出力します。
* このサンプルでは標準出力に文字列として出力しています。
*/

public void createFeed(){
SyndFeed feed = (SyndFeed)new SyndFeedImpl();
feed.setFeedType(feedType);

feed.setTitle(title);
feed.setLink(link);
feed.setDescription(description);

feed.setEntries(entries);

SyndFeedOutput output = new SyndFeedOutput();
try {
//サンプルとして文字列として生成。
//ファイルとして出力するならoutputメソッドを利用。

String feedText = output.outputString(feed);
System.out.println(feedText);

} catch (FeedException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}

}
}





上記のクラスを使ってRSS 2.0のフィードを生成するには、こんな感じ。



package jp.boldweb.feed.driver;

import java.util.Date;
import jp.boldweb.feed.core.FeedCreator;

public class FeedCreatorDriver {

/**
* 動作確認用ドライバ
* @param args
*/

public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
FeedCreator feed = new FeedCreator("rss_2.0");
feed.setFeedTitle("WEB上のボクについて");
feed.setFeedLink("http://www.geocities.jp/kashi57move/");
feed.setFeedDescription("ボクがWEB上で展開しているサイトやブログの情報です。");

feed.setTextEntry(
"技術への名残り"
, "http://kashi57move.blogspot.com/"
, "IT技術やマーケティング関連を中心に思いつくままに書いています。"
, new Date());

feed.setTextEntry(
"ぼや記"
, "http://blog.livedoor.jp/kashi57move/"
, "くだらない日常を出来るだけくだらなく書き留めているつまらない日記です"
, new Date());

feed.setTextEntry(
"kashi57move web"
, "http://www.geocities.jp/kashi57move/"
, "昔ながらの個人的HP。日記がメインでしたがブログに移行したので、ここ数年更新していません。"
, new Date());

feed.setTextEntry(
"BOLDWEB"
, "http://www.boldweb.jp/"
, "仕事用のHPですが、まだまったく手を付けられていません…。"
, new Date());

feed.createFeed();
}

}




RSSの違うバージョンやAtomフィードを作りたかったら、コンストラクタの引数に指定してください。指定できるのは(試したのは)以下。
"rss_1.0"
"rss_2.0"
"rss_0.9"
"rss_0.92"
"atom_0.3"
"atom_1.0"

いわゆる業務システム用に業務別のフィードを何種類か作らないといけない場合は、FeedCreator(名前はちょっといただけないな…)を継承してそれぞれ専用クラスを作れば、多少扱いやすくなるかな?

あと、上記のままだと時間表記がUSになってしまうので、正確に出すならイジくらないといけないかも。
こちらが参考になるかと。
ROMEでRSS出力、でも日本時間はダメ?

一応コンパイルして実際に動いてますが、例によって何かおかしな点等あればコメントいただけるとこれ幸い。

2 件のコメント:

ms2 さんのコメント...

毎度細かいこと。

SyndFeed feed = (SyndFeed)new SyndFeedImpl();

SyndFeed feed = new SyndFeedImpl();

で良いと思うよ。キャストはきっといらないはずさ。確認してみてちょ。

あと、自分ならcreateFeedを何か工夫しそうだね。出力形式をいじれるように。でも、とりあえず出すなら十分さね。

Takamitsu Kashiwa さんのコメント...

毎度ありがとうございます。多謝。

うん。キャストいらないね。
Implementしてるクラスでキャストが必要っておかしいもんなw

やはりcreateFeed()の手抜きがバレてしまいましたか。
そこは、使う人の創意工夫で(逃っ...)