使用 RSS 和 Atom 实现新闻联合
RSS 和 Atom 技术的出现为新闻联合(news syndication)带来了一个崭新的时代。不管怎样,Web 站点管理员每天手动发布新闻并管理电子邮件用户都需要花费时间。本文说明了如何使用 RSS 和 Atom 联合格式实现通用的新闻发布体系结构,使发布过程变得轻松,并将人为错误减至最少。
RSS 和 Atom 联合
RSS 和 Atom 是相似的基于 XML 的文档格式,描述被称为摘要(feed)的相关信息列表。这些摘要由许多项组成,每项都带有一套可扩展的附加元数据;例如,每项都有一个标题。这些摘要的主要用途是用于 Web 内容联合,比如用于 Web 站点和直接用于用户代理的 Weblog 或者新闻标题。
<?xml version="1.0"?> <rss version="2.0"> <channel> <title>Feed Title</title> <link>http://yourwebsite.com/</link> <description>Feed Description</description> <language>en-us</language> <pubDate>Mon, 03 Jan 2005 12:00:00 GMT</pubDate> <item> <title>Article Title</title> <link>http://yourwebsite.com/articlelink.html</link> <description>Your content included here.</description> </item> <item> <title>Sports</title> <link>http://yourwebsite.com/sportslink.html</link> <description>Your content included here.</description> </item> </channel> </rss> |
清单2. Atom 1.0 feed 示例
<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <title> Feed Title </title> <link href=" http://yourwebsite.com/"/> <updated>2003-12-13T18:30:02Z</updated> <author> <name>Your Name</name> </author> <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id> <entry> <title>Article Title</title> <link href=" http://yourwebsite.com/articlelink.html "/> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> <updated>2003-12-13T18:30:02Z</updated> <summary>Some text.</summary> </entry> <entry> <title>Sports</title> <link href=" http://yourwebsite.com/sportslink.html "/> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344e45ab90</id> <updated>2003-12-14T13:30:55Z</updated> <summary>Some text.</summary> </entry> </feed> |
从前面的两个例子(清单 1 和 清单 2)可以看出,RSS 和 Atom 具有相似的基于 XML 的格式。它们的基本结构是相同的,只在节点的表达式上有一点区别。
每个摘要文件实际上代表一个通道。它包含通道标题、链接、描述、作者等等。通道信息提供关于摘要的基本信息。通道信息之后是一些项。每项代表一篇可以从摘要阅读器阅读的真实的新闻或者文章。通常情况下,每项包含有标题、链接、更新时间和摘要信息。
参考 RSS 2.0 and Atom 1.0, Compared,回顾 RSS 和 Atom 的不同点。
表 1. 比较 RSS 2.0 和 Atom 1.0
不同点 | RSS 2.0 | Atom 1.0 |
---|---|---|
部署 | RSS 2.0 得到广泛部署。 | Atom 1.0 还未得到广泛部署。 |
规范 | 哈佛大学拥有版权并冻结了 RSS 2.0 规范。 | Atompub 工作组(属于 IETF)就 Atom 1.0 规范达成一致意见,并在将来有可能重新修订。 |
所需内容 | RSS 2.0 包含所需的摘要级别的标题、链接和描述。它不需要在摘要中出现的任何单独项的字段。 | Atom 1.0 包含摘要和条目所需的标题(可以为空)、惟一标识和最后更新的时间戳。 |
有效负载(payload) | RSS 2.0 可以包含普通文本或者转义 HTML,但是不能分辨所提供的是两个中的哪一个。 | Atom 1.0 包含有效负载容器。 |
全部或者部分内容 | RSS 2.0 有一个 <description> 元素,可以包含条目的全部文本或者大纲。它没有用于标识内容是否完全的内置方法。 |
Atom 1.0 提供单独的 <summary> 和 <content> 元素 。如果它是非文本的或者非本地的内容,出于可访问性的原因摘要将很好用。 |
自动发现 | RSS 2.0 用不同的方法实现自动发现。 | Atom 1.0 标准化自动发现。 |
提取和聚合 | RSS 2.0 只有一个可识别的形式:一个 <rss> 文档。 |
Atom 1.0 允许独立的 Atom Entry 文档,可以使用任何网络协议传输;例如,XMPP。Atom 也支持聚合摘要,其中,条目指向它们来自的摘要,前提是如果它们将被包含到其他摘要中。 |
随着 RSS 和 Atom 格式规范的发展和完善,可以实现越来越多的 Web 应用程序。使用 RSS 或 Atom 的最通用和典型的实现是新闻发布系统。
以下是一个使用 RSS 和 ATOM 摘要实现发布系统的通用体系结构。这个体系结构由三部分组成:
- 摘要生成器子系统
- 摘要运行子系统
- 自动发布子系统
现在分别看一下这三个子系统的详细内容。
摘要生成器负责生成基于 XML 的摘要文件。摘要生成器的类图如下所示:
图 1. 摘要生成器的类图
摘要生成器的核心是 FeedFileManager
类。它生成与一个特定摘要相关的 XML 文件。摘要有两种具体的类型:AtomFeed
和 RssFeed
。这两种 feed 类都包含一个 feed channel 类和一个 feed item 类。feed channel 类和 feed item 类的实现将根据它们不同的构造而不同。
摘要运行子系统提供了几个摘要运行函数,用于运行这两种类型的摘要文件。例如,insertItem()
、deleteItem()
、updateItem()
函数。摘要运行子系统的类图如下所示:
图 2. 摘要运行子系统的类图
首先,需要一个抽象工厂模式 PublisherFactory
生成两个摘要发布者之一。然后这个发布者通过 DataCollection
类从数据库中提取数据。
自动发布子系统是在固定时间更新摘要文件的计时器。它利用前面两个子系统并使发布系统运行。
图 3. 自动发布子系统的类图
现在,来看看每一步的详细实现过程。首先,图 4 提供了通用实现过程的图表。它显示了几个主要的构建块以及它们之间的关系。
图 4. 实现过程概览
整个应用程序是一个大计时器,所以可以在它内部设置固定的启动时间。当时间一到,计时器开始做预定的工作 —— 生成摘要文件。首先,应用程序生成一个 XML 文件,然后形成 RSS 和 Atom 摘要,最后向创建的 XML 文件中写入这些摘要。摘要的来源可以是数据库、文件或者各种其他的资源。
计时器是发布系统的核心。它触发系统根据用户的指定时间或者在每天的固定时间生成摘要文件。对于 Java 应用程序,通常可以使用 Java 标准调度类:Timer
和 TimerTask
来实现一个重复执行的调度任务。
更一般的是在这个发布系统中组合调度循环任务。如何组合调度循环任务的详细信息可以参考 在 Java 应用程序中计划重复执行的任务。
清单 3. Timer start 方法示例
public void start() { SchedulerTask st = new SchedulerTask(){ public void run() { try { updateNewsFeeds(); //concrete method of update feed files. updateBooksFeeds(); ... } catch (Exception e) { e.printStackTrace(); } } }; |
RSS 和 ATOM 摘要都是基于 XML 的,所以在实现过程中生成这些基于 XML 的文件是很重要的。在摘要生成器子系统中的 FeedFileManager
类负责这项任务。
图 5. FeedFileManager 类
通常,这个类应该包括 createFeedFile()
方法。这个方法需要做三件事:
- 创建一个 XML 文件。要达到这个目标,可以创建一个静态方法 createXMLFile()。
- 与 “摘要运行子系统” 进行交互来创建相关通道和项信息。
- 把所有信息写回 XML 文件。
清单 4. createFeedFile 方法示例
public String createFeedFile(String channelid, String name, String type) throws Exception { ... createXMLFile(file, type); IPublishable publisher = PublisherFactory.createPublisher(type, file); Feed feed = getFeed(type); Channel channel = feed.getChannel(); ArrayList itemlist = feed.getItemList(); publisher.insertChannel(channel); publisher.insertItemList(itemlist); publisher.writeback(file); return file; } |
在上一个过程中,发布工厂创建了一个发布者并向某一摘要插入相关的通道信息和项列表。
清单 5. 插入通道和项列表的示例代码
publisher.insertChannel(channel); publisher.insertItemList(itemlist); |
要形成精确的通道和项列表,就要从数据库中取出数据并向摘要模式中输入取出的数据。下面演示了如何取出数据,然后向相关 databean 中输入信息:
清单 6. 摘要的示例代码
... NewsBeanManager newsmanager = new NewsBeanManager(); newslist = newsmanager.getAllNews(); //interact with database ... for (Iterator it = newslist.iterator(); it.hasNext(); it.next()) { title = "News " + i + ": " + ((NewsBean) newslist.get(i)).getTitle(); link = ((NewsBean) newslist.get(i)).getLink(); author = ((NewsBean) newslist.get(i)).getAuthor(); timestamp = ((NewsBean) newslist.get(i)).getPublishTime(); id = String.valueOf(((NewsBean) newslist.get(i)).getNewsID()); description = ((NewsBean) newslist.get(i)).getSummary(); content = ((NewsBean) newslist.get(i)).getContent(); rssitem = new RssItem(title, link, author, timestamp, id, description); rssitemlist.add(i, rssitem); atomitem = new AtomItem(title, link, author, timestamp, id, description, content); atomitemlist.add(i, atomitem); i++; } |
在成功地实现新闻发布系统之后,您可能会受益于以下的部署技巧。
要满足最流行的摘要阅读器的需要,在生成摘要文件时要注意以下几点。
- 在 XML 文件头添加 RSS 和 Atom 版本信息,如 清单 7 所示:
清单 7. 添加 RSS 和 Atom 版本信息的示例代码
<?xml version="1.0" encoding="utf-8"?> <rss version="2.0"> ... <?xml version="1.0" encoding="utf-8"?> <atom version="1.0">
- 为 RSS 和 Atom 通道提供链接信息。在 RSS 2.0 中,链接信息显示为节点,但是在 Atom 1.0 中,链接信息显示为属性。虽然链接对于 Atom 来说不是强制项,但是为通道部分提供链接信息是一种不错的做法(参见 清单 8)。
清单 8. 为通道提供链接信息的示例代码
<?xml version="1.0" encoding="utf-8" ??> <rss?> <channel?> <title?>News Syndication</title?> <link?>http://www.newssyndication.com</link?> <description?>this is a news feed</description?> ... <?xml version="1.0" encoding="utf-8" ??> <feed xmlns="http://www.w3.org/2005/Atom"?> <title?>News Syndication</title> <link href="http://www.newssyndication.com" /?> <updated?>2006-07-06T10:26:30Z</updated?> <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id?> |
在 XML 文件头中添加编码信息。
清单 9. 在 XML 文件头中添加编码信息的示例代码
<?xml version="1.0" encoding="utf-8"?> |
当实现写 XML 文件的函数时,使用 OutputStreamWriter
代替 FileWriter
把编码设置为 utf-8。FileWriter
的默认编码是 “GBK”。
清单 10. 使用 OutputStreamWriter 把编码设置为 utf-8 的示例代码
OutputStreamWriter writer = new OutputStreamWriter(outputstream,"utf-8"); |
本文中,首先回顾了 RSS 和 Atom 摘要的相似点和不同点,然后考察了使用两种摘要类型实现发布系统的体系结构。这种体系结构包括三个子系统,彼此相互配合工作。接下来在逐步演示之后,向您介绍了一些实现过程的技巧。现在您可以享受在新闻摘要中应用这些高效方法了。
学习
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文 。
- 什么是 Atom?:Atom 的快速入门。
- RSS 2.0 and ATOM 1.0, Compared:关于 RSS 2.0 和 Atom 1.0 之间的区别的详细信息。
- RSS 2.0 规范:学习整个规范。
- RSS and Atom feed:在深入研究 developerWorks 站点之后,构建自己的 RSS 和 Atom 摘要。
- RSS 教程:学习 RSS 是什么、如何开始以及如何使用它。
- Workplace RSS feed and blog:从 Workplace 讨论论坛、Workplace 产品支持页面、developerWorks Workplace 文章和 developerWorks Workplace 教程中获得最新内容。
- 在 Java 应用程序中计划重复执行的任务(Tom White,developerWorks,2003 年 11 月):阅读关于 Java 语言中
Timer
类的总结。
- developerWorks Web 开发专区:关于 Web 技术的文章和教程可以提升您的站点开发技能。
- developerWorks 技术事件和网络广播:关注和了解技术的最新发展,缩短学习进程,改进最困难的软件项目的质量和结果。
原文地址:http://www-128.ibm.com/developerworks/cn/web/wa-syndrssatom/index.html?ca=drs-#listing1