我的目标是做一个简单的portletQ每ơ读取新的RSS站点昄最新的新闻条目?br />
׃一个下午,去sourceforge和google 上搜?opensource ?java rss libQ还真有不少Q顺便提一下,sourceforget的搜索真的很烂)。简单过滤以后,觉得以下三个cd比较有搞头。Rome 、rssutils和rsslib4j。具体的评测如下Q?br />
一. Rome
Rome ?java.net 上的一个开源项目,现在的版本是0.5。ؓ(f)什么叫Rome呢,按它的介l上的说法,有个“条条大\通罗?#8221;的意思,有些RSS的意呟뀂Rome可能?sun 公司从自己某个子目中抽d来的Qpackage和类的命名就象j2sdk一h觉规范。功能上支持RSS的所有版本及(qing) Atom 0.3(Atom是和RSScM的一U内容聚合的方式)。Rome 本n是提供API和功能实玎ͼ其下独立Z?rome-fetcher 目Q专门用来读取RSS内容。正和我意啊?br />
参照 fetcher 上的范例Q解?RSS 相当单,代码片断如下Q?br />
FeedFetcher fetcher = new HttpURLFeedFetcher();
SyndFeed feed = fetcher.retrieveFeed(feedUrl);
System.out.println(feedUrl + " has a title: " + new String(feed.getTitle().getBytes("iso8859-1"), "utf-8") + " and contains " + feed.getEntries().size() + " entries.");
for (Iterator iter = feed.getEntries().iterator(); iter.hasNext(); ) {
SyndEntry entry = (SyndEntry) iter.next();
System.out.println("<a href=" + entry.getLink() + ">" + entry.getTitle() + "</a>[" + entry.getPublishedDate() + "]");
}
Z么用 new String(feed.getTitle().getBytes("iso8859-1"), "utf-8") q行转码Q是因ؓ(f)Rome来解?新浪新闻 RSS的时候试图从 URLConnection ?header 中得到编码信息,否则L?iso8859-1。而新的RSS response header 中不包含~码信息Q所以要做一番{码。另外还有就?entry.getPubDate() 也将q回nullQ因为Rome 用多Upattern 去试图解析时间信息,新浪的时间格式还是符合RFC822的,但是Rome 使用SimpleDateFormat 来解析时_(d)它忘C一点,是 SimpleDateFormat的解析是兌?Locale 的,所以由于我本地l(f)ocale是ChinaQSimpleDateFormat的parseҎ(gu)解析不出英文的时间字W。以上代码前?Locale.setDefault(Locale.Englisth) 可以搞定Q但总觉得不爽?br />
如果也不惌{码的话,Rome q提供了一?XmlReader 的类Q通过分析 header ?xml 内容推断 encodingQ修?HttpURLFeedFetcher 的源?:
// 改变 InputStreamReader , 换用 XmlReader
//InputStreamReader reader = new InputStreamReader(is, ResponseHandler.getCharacterEncoding(connection));
XmlReader reader = new XmlReader(connection);
SyndFeedInput input = new SyndFeedInput();
SyndFeed feed = input.build(reader);
那么中文不用转码也能正确昄了,不过修改源码后我再解?nbsp;癑ֺ新闻 RSS 的时候,底层的JDOM却会(x)抱错说xml 格式不正。也许Rome的开发者也遇到q这L(fng)问题Q所以才没有使用 XmlReader?br />
? rssutils
它是一个工具包Qsun ?develope站点上有文章 RSS Utilities: A Tutorial 专门介绍用taglib 昄RSS内容Q附带的可以下蝲q个工具包,但我从网上搜索不到它的出处,自然也无法看到它的源码。但从反~译的代码来看,也是sun公司内部高手所做,设计_yQ代码简l。实C个handlerQ用sax的方式解析xml内容Qhandler内部用反和javabean的机制构造RSS元素对象q赋倹{代码片断如下:(x)
RssParser parser = new RssParserImpl();
Rss rss = parser.parse(new URL(url));
System.out.println(rss.getChannel().getTitle());
for (Iterator iter = rss.getChannel().getItems().iterator(); iter.hasNext();) {
Item item = (Item)iter.next();
System.out.println("<a href=" + item.getLink() + "</a>" + item.getTitle() + " " + item.getPubDate());
}
如上所C,代码也是相当单,没有转码的需求,旉也正显C(因ؓ(f)Ҏ(gu)没做分析Q当字符串直接返回)。但是该工具包ƈ非真正对外公布,代码中有些不严}的地方,如System.out的输出,很不爽。而且如果 RSS ?xml内容如果~少部分不常用元?Q它也会(x)printStackTrace一大串Q服了它了。另外还有一个大问题Q就是当我用它解?癑ֺ新闻 的时候,直接报错:(x)org.xml.sax.SAXParseException: 字符转换错误Q?#8220;Unconvertible UTF-8 character beginning with 0xb0”。网上查了查Q可能是 java 修改q的 UTF-8 和标?UTF-8 些微不兼容导致。详情参?Java q_中的增补字符 一文?br />
? rsslib4j
rsslib4j ?sourceforget 上的目Q主| http://sourceforge.net/projects/rsslib4jQ现在最新的版本?.2Q才0.2Q可是开发状态却已经是稳定品化了。同h持所有RSS版本?br />
rsslib4j 解析 RSS 的方式和 rssutils 一P我看了看源码Q设计比较简单,代码可读性一般,大量使用if。代码片断如下:(x)
RSSHandler hand = new RSSHandler();
RSSParser.parseXmlFile(new URL(url), hand, false);
RSSChannel ch = hand.getRSSChannel();
System.out.println(ch.toString());
LinkedList lst = hand.getRSSChannel().getItems();
for (int i = 0; i < lst.size(); i++) {
RSSItem itm = (RSSItem) lst.get(i);
System.out.println(itm.toString());
}
看v来也是相当清晰易懂,执行l果也和rssutils一P不过用它来解?癑ֺ新闻 却不?x)出?rssutils 的utf-8~码错误Q真是奇怪,两者都是调JAXP?SAXParser 。不q它的代码也有bugQ不能解析出 channel 的一些信息,查看源码Q有点简单逻辑错误Q修正后解决。想写封emaill项目开发者可惜英文不行,通过cvs去commit一下也嫌麻烦,作Ş?br />
ȝ
Rome:
?- 1Q可扩展性好Q有前途?Q功能强大,除了用来解析RSSQ还可以聚合和构造RSS?br />
?- 1Q兼Ҏ(gu)待加强Q?Q绑定jdom。ؓ(f)什么不喜欢 jdom呢,因ؓ(f)它api 老变Q还很绝Q搞得不兼容?br />
rssutils:
?- 1Q代码设计精妙,值得学习(fn)?Q附?taglib 实现Q直接可?jsp 中应用?br />
?- 1Q没有源码?2Q兼Ҏ(gu)有待加强?3Q功能较弱,只能用来解析RSSQ没有聚合和构造RSS功能?br />
rsslib4j:
?- 1Q简单有效,体积?Q兼Ҏ(gu)不错?br />
?- 1Q有bug?Q功能较弱,只能用来解析RSSQ没有聚合和构造RSS功能?br />
~辑选择Q?rsslib4j
我只用来读读新浪新闻Qrsslib4j 够用好Q不q要自己修改和编译源码?br />
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=282333

]]>