级别: 初级 朱 可, 软件工程师, IBM 中国软件开发中心
2009 年 10 月 19 日 本文将为 Web 开发者提供使用和开发 feed 的若干最佳实践,包括 WebSphere® sMash 新版本中为这些最佳实践提供的支持和实际的代码片段。读者可以体验到如何在 Web 应用程序中使用 feed 轻松完成信息聚合工作,以及实际例子带来的有趣效果。
Feed 的基本概念
在互联网发展的早期,随着信息发布变得越来越频繁,单纯使用传统的远程 HTML 文档来直接查看信息的方式逐渐难以满足用户对信息消费时效性的需要。这要求信息发布商们寻找新的方式来将更新的内容及时发送给用户,于是 Web feed 应运而生,它实际上是一种以 XML 为基础的数据格式,通常被用来发布那些互联网上频繁更新的内容,如博客、滚动新闻等等。
feed 的用途
大家在浏览网页时看到的橘红色图标 就是 feed 的标志。点击这个图标就可以看到由互联网内容服务商提供的 feed,用户可以使用浏览器通过 feed 的 URL 地址获取更新内容。如使用 Firefox 浏览器,遇到提供 feed 的网页,用户可以通过单击地址栏右侧的 feed 图标来订阅该网页提供的内容更新。
用户还可以使用专用的 feed 阅读器“订阅”这些 feed,根据个人的阅读喜好有选择的阅读。现在流行的在线阅读器如 Google Reader, 国内的鲜果网,还针对 feed 内容提供如分享、讨论、加标记等功能,方便在朋友、同事和社会网络中共享信息和知识。
feed 的特点
从开发人员的角度来看,feed 是一种包含指向资源链接和一系列元数据的 XML 文档。目前最为流行的 feed 格式主要包括 RSS 和 Atom。
RSS 主要包括 4 部分:channel(包含 feed 发布者提供的元数据)、image(图标、图片)、item(feed 中更新的条目)和 text (用户提供反馈信息的表单)。目前最常用的是 RSS 2.0 版本。感兴趣的读者可以通过参考资料中的文章来了解 RSS 格式的详细内容。
针对 RSS 在国际化、内容复用性不足方面,Atom 提供了更严谨全面、更具可扩展性的 feed 数据格式和发布协议。现在我们讨论的 Atom,往往指以 IETF 组织提出的 Atom 1.0。
清单 1. Atom 1.0 样例
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Atom-Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>
|
feed 的优势
相比每次使用电子邮件,使用 feed 作为信息发布的方式具有多种优势。包括用户无需提供个人邮件地址、随时订阅随时退订、feed 提供的信息摘要和资源链接更方便用户阅读等等。对网站开发人员来说,采用 feed 格式来发布内容数据,可以给用户更多的阅读选择。用户通过第三方的 feed 阅读器有选择地查阅,也可以通过聚合、过滤、排序、分享等手段将自己感兴趣的内容组成新的 feed 重新发布,这大大提高了信息更新的时效性,而且更有益于信息的有效传播。
通常 feed 中往往包含供人阅读的内容信息,如新闻、博客、相册等等。近些年来随着 Web 2.0 的不断流行,feed 也被用来发布结构化的数据:如 Google 在线电子表格数据、IBM 在线社区更新等等,甚至目前流行的在线开放 API 也采用 feed 作为数据格式,如 Yahoo! 搜索、豆瓣等等。
WebSphere sMash 中对 feed 的支持
WebSphere sMash 作为 IBM 面向 Web2.0 应用程序提供的开发和运行平台,针对开发人员使用 feed 的不同场景提供了多种支持,主要目的是让使用基于 feed 的技术和协议变得更简易,避免针对协议细节的编程。在 sMash 中有多个组件为 feed 编程提供不同类型的支持,详见表 1。在简单的文字介绍之后,本文将提供多个简单场景的创建过程,展示 sMash 为 feed 编程带来的简单性和趣味性。 表 1. WebSphere sMash 中 feed 相关组件介绍
|
模块名称
|
用途
| |
zero.atom
|
提供读取和输出 Atom 1.0 类型的 XML 文档的编程接口,包括将文档内容发布成为 feed 和一系列配置功能。
| |
zero.rss
|
消费和发布 RSS 类型的 feed,得益于开放源代码项目 Rome 提供的扩展库,zero.rss 模块提供多种流行 RSS feed 间的格式转换功能。
| |
zero.feed
|
提供服务器端和浏览器端操作 feed 内容的编程接口,包括 Java、Groovy 和 Ajax 风格的 API.
| |
zero.resource
|
通过 Zero 资源模型提供一种高度简化的方式来创建 RESTful 资源,程序员可以通过该组件轻松发布基于 Atom 的开放编程接口。
| |
zero.assemble.flow
|
通过 Assemble flow 调用第三方 REST 服务的功能,程序员可以轻松为各种 REST 服务提供者提供 feed 格式的数据视图。
|
为数据提供 feed 视图
第一个例子介绍如何为已有的数据提供 feed 视图。这里用一个 MySQL 数据库代表数据源,有一张表 blog_posts 保存演示用的内容数据。Groovy 脚本将从中读取最新的 10 条记录,并为其提供 Atom 数据格式的 feed 视图。
1. 首先用 sMash 命令行工具创建应用程序 feedview.demo;
zero create feedview.demo
|
2. 在创建好的 sMash 应用程序的依赖管理配置文件 config/ivy.xml 中加入所需的模块。
清单 2. 使用 zero.atom 和 zero.data 模块,以及 MySQL 的 JDBC 驱动
<dependencies>
<dependency org="zero" name="zero.core" rev="[1.1.0.0, 2.0.0.0["/>
<dependency org="zero" name="zero.atom" rev="[1.1.0.0, 2.0.0.0["/>
<dependency org="zero" name="zero.data" rev="[1.1.0.0, 2.0.0.0["/>
<dependency org="mysql" name="mysql-connector-java" rev="5.1+"/>
</dependencies>
|
3. 创建 Groovy 脚本并保存至 public/latest_posts/atom/index.groovy。
清单 3. 从数据库获取内容数据、创建 Atom 的数据结构,并将其发布成为一个 Atom feed
// file: /public/latest_posts/atom/index.groovy
try {
// Get configured DataManager for data access
def data = zero.data.groovy.Manager.create('blog_db')
// Retrieve posts data
def result = data.queryArray(
'SELECT ID as id, post_date as updated, content as summary '
+ 'FROM blog_posts order by updated desc limit 0, 10')
def feed = [
title: "latest 10 posts",
updated: new Date(),
entries: result
]
request.docType = 'feed'
request.view = 'atom'
request.atom.output = feed
render()
} catch (Exception e) {
request.status = HttpURLConnection.HTTP_INTERNAL_ERROR
request.error.message = e.getMessage()
request.view = "error"
render()
}
|
4. 当然你还需要在配置文件 config/zero.config 中加入必要的信息来连接数据库。
清单 4. 连接 MySQL 数据库
/config/db/blog_db = {
"class" : "com.mysql.jdbc.jdbc2.optional.MysqlDataSource",
"serverName" : "localhost",
"portNumber" : 3306,
"databaseName" : "MYDBNAME",
"user" : "someuser",
"password" : "secretpasssword"
}
|
5. 在命令行中输入如下命令来解析、获取相关的模块,并启动这个 sMash 应用程序:
6. 使用浏览器访问 http://localhost:8080/latest_posts/atom/,你将会看到已经发布为 Atom feed 的数据。
个性化 feed 内容
除了将已有内容发布成 feed 之外,另一个主要的使用场景即为消费第三方提供的 feed 内容。sMash 提供了 zero.feed 包为消费和处理第三方的 feed 数据提供了丰富的功能支持和非常简单易用的 API。以查看搜狐 IT 新闻为例,用户只需要查看当天的内容,这时候你可以使用 zero.feed 组件提供的编程接口创建几行脚本就搞定了!
1. 使用命令行工具创建名为 personalfeed.demo 的 sMash 应用程序:
zero create personalfeed.demo
|
2. 在 sMash 应用程序的依赖管理文件 config/ivy.xml 中增加对 zero.feed 模块的依赖:
清单 5. 使用 zero.feed 模块
<dependencies>
<dependency org="zero" name="zero.core" rev="[1.1+,2.0.0.0["/>
<dependency org="zero" name="zero.feed" rev="[1.1+,2.0.0.0["/>
</dependencies>
|
3. 创建脚本文件 /public/sohuITtoday/index.groovy:
清单 6. 使用 Groovy feed API
// set response header "Content-Type"
headers.out."Content-Type" = "application/atom+xml"
// fetch sohu IT news feed and filter only today
zero.feed.FeedFactory.fetch("http://news.sohu.com/rss/it.xml")
.after("-P1D")
.writeTo(request.writer[])
|
4. 启动 sMash 应用程序,访问地址 http://localhost:8080/sohuITtoday/ 即可。
5. 如果你还需要查看新浪 IT 和网易 IT 新闻,还可以将他们聚合起来变成一个 feed. 在 personalfeed.demo 应用程序中创建文件 /public/ITtoday/index.groovy:
清单 7. 聚合并过滤 feed 内容
// set response header "Content-Type"
headers.out."Content-Type" = "application/atom+xml"
zero.feed.FeedFactory.aggregate(
"http://news.sohu.com/rss/it.xml",
"http://rss.sina.com.cn/news/allnews/tech.xml",
"http://tech.163.com/special/00091JPQ/rssit.xml")
.after("-P1D")
.writeTo(request.writer[])
|
最后在浏览器中访问地址 http://localhost:8080/ITtoday/,你将会看到一个 feed 包含了 3 大网站的 IT 新闻。
除了编写服务器端运行的 Groovy 来获取 feed 数据之外,zero.feed 模块还提供 Ajax 风格的 JavaScript feed 编程接口。这意味着 Web 开发者只需要浏览器即可针对 feed 进行编程。为了简化 JavaScript 访问 feed 数据时冗长的方法调用,Web 开发者可以使用 JSON 格式来代理 XML 格式来访问 feed。
这里仍以访问搜狐 IT 新闻为例,直接创建 HTML 文件 public/sohuITToday/sample.html:
清单 8. 使用 JavaScript 访问 feed
<html>
<head>
<script type="text/javascript" src="/dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("zero.feed.Feed");
</script>
<script type="text/javascript">
function fetchSohuIT() {
zero.feed.FeedFactory.fetch("http://news.sohu.com/rss/it.xml")
.after("-P1D")
.loadAsJSON(function(feed) {
var items = feed.entries;
var htmlContent = "";
for (var i = 0; i < items.length; i++) {
var title = items[i].title;
var link = items[i].links[0].href;
htmlContent += "<a href='" + link + "' target='_blank'>"
+ title + "</a><br/>";
}
dojo.byId("feed").innerHTML = htmlContent;
});
}
</script>
</head>
<body>
<p>This sample shows how to get resulting feed in JSON format.</p>
<button onclick="fetchSohuIT();" dojoType="dijit.form.Button">
load sohu IT news!
</button>
<div id="feed"></div>
</body>
</html>
|
运行 sMash 应用程序,访问 http://localhost:8080/sohuITtoday/sample.html, 单击按钮“load sohu IT news!”,稍后就可以看到如图 1 所示。
图 1. Ajax feed API 访问搜狐 IT 新闻
为数据服务提供 REST 风格的 API
 |
ZRM 是什么?
ZRM 是 Zero 资源模型(Zero Resource Model)的缩写,它提供了一种创建 RESTful 资源的简便方法,你可以轻松创建出 REST 风格的数据服务。 |
|
为数据服务提供开放 API 可以方便第三方数据消费者使用数据服务,而使用 REST 风格构建 API 已经成为目前最为普遍的做法。以豆瓣网提供的开放 API 为例,它提供 REST 风格的 URI, 并且使用 Atom 1.0 作为数据格式,方便开发者编写程序访问豆瓣提供的各种数据服务。使用 sMash 你可以轻松地创建这样的开放 API。
我们使用 sMash ZRM 创建一个简单的联系人管理程序。在这个应用程序中,我们将为联系人数据提供 RESTful API。为了简化开发过程,推荐读者使用 WebSphere sMash 的开发工具 AppBuilder。
1. 打开 AppBuilder 创建 sMash 应用程序 contact.demo。
图 2. 使用 AppBuilder 创建应用程序 contact.demo
2. 为联系人信息创建一个 Zero 资源模型 (ZRM),指定相关的列名称和数据类型。
图 3. 选择创建文件类型 ZRM model
图 4. 创建 ZRM model /app/models/contact.json
图 5. 使用 ZRM model 编辑器指定列名称和数据类型
图 6. 创建 resource handler app/resources/contact.groovy
3. 创建数据库和样例数据。
图 7. 切换到 Console 标签运行命令 zero model sync 创建数据库表
图 8. 为样例数据创建 SQL 脚本 /init_data.sql
图 9. 运行 SQL 脚本导入样例数据 : zero runsql init_data.sql
这时候单击 AppBuilder 右上角的 “Start” 按钮启动 contact.demo 应用程序,在浏览器中打开地址 http://localhost:8080/resources/contact?format_as=atom 即可看到 feed 格式的联系人信息。
zero.resource 模块为以上 RESTful API 接口提供丰富的查询功能支持。如 http://localhost:8080/resources/contact?telephone_startswith=158&format_as=atom 将列出所有电话号码以 158 开始的联系人信息。
4. 为了保护数据服务的安全,你应该为开放的数据服务提供安全认证。这里可以利用 sMash 的安全特性方便的将 REST API 保护起来。 在 config/zero.config 中加入如下配置:
清单 9. 安全设置
@include "security/enableSecurity.config"
# secure contact API by basic authentication
@include "security/basicAuthentication.config" {
"conditions": "/request/path =~ /resources/contact(/.*)?"
}
# only people in group “friends” can access contact API
@include "security/authorization.config" {
"conditions": "/request/path =~ /resources/contact(/.*)?",
"groups" : ["FRIENDS"]
} |
这段配置信息为访问联系人的 REST API 提供 HTTP 基本身份验证,并且授权只有名为 FRIENDS 的群组成员可以访问。
为第三方服务提供 feed 数据视图
虽然 feed 已经成为 Web 2.0 流行风潮中数据服务最常见的发布格式,但现实 Web2.0 世界仍旧存在大量数据服务并没有使用 RSS 或 Atom 等格式,如 Amazon Web Services,Ebay Web Services 等提供的 HTTP API。使用 WebSphere sMash 可以连接这类数据服务,并且提供将 XML 格式的数据转换成 feed 格式。
这里以 Last.fm 提供的 Track Search 服务为例,通过 XSL 和一个 groovy 方法来为 Last.fm 提供 feed 格式的数据视图。
1. 第一步当然是创建 sMash 应用程序,这里直接介绍接下来的步骤。打开 AppBuilder 的 Dependencies 标签中的 “Add” 按钮,选中 zero.assemble.flow。
图 10. 使用 zero.assemble.flow 模块
2. 为 TrackSearch 服务提供服务描述文件 app/assemble/services/LastfmSearch.xml。
清单 10. 服务描述文件片段
<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:z="http://www.projectzero.org/assemble/component">
<title>Last.fm Web Services</title>
<link rel=
"http://www.projectzero.org/assemble/component/url-template"
type="text/xml"
href="http://ws.audioscrobbler.com/2.0/?method=
{method}&api_key={apiKey}&artist=
{artist?}&track={track}"
/>
...... |
3. 创建 XSL 文件 public/stylesheet/lastfm.xsl 将 Last.fm 提供的结果转换成为 Atom feed
清单 11. 格式转换文件片段
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/2005/Atom"
xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">
<xsl:template match="/">
<feed><title>
Search result for <xsl:value-of select=
"lfm/results/opensearch:Query/@searchTerms"/>
</title>
<opensearch:totalResults>
<xsl:value-of select="lfm/results/opensearch:totalResults"/>
</opensearch:totalResults>
<xsl:apply-templates select="lfm/results/trackmatches/track"/>
</feed>
</xsl:template>
...... |
4. 在 config/zero.config 中填入你的 API Key:
/config/lastfm/apiKey = "Last.fm API Key: http://www.last.fm/api/account"
5. 最后创建 Groovy 脚本 public/testTrackSearch/index.groovy 调用这个 TrackSearch 服务。这里使用关键词 "Believe" 进行搜索:
清单 12. Groovy 脚本调用 Track Search 服务
def criteria = [method: "track.search", track: "Believe", format: "atom"]
// use service description file /app/assemble/services/LastfmSearch.xml
def results = invokeService("TrackSearch", criteria)
// rendering
request.view = "XML"
request.xml.output = results
headers.out."Content-Type" = "application/atom+xml"
render() |
启动这个应用程序,在浏览器中输入 http://localhost:8080/testTrackSearch 即可看到如图 11 所示的 feed。
图 11. 为 Track Search 服务提供 feed
综合范例:统计 digg.com 热门文章的 dig 数量
我们已经通过上面的内容了解了 sMash 为 feed 的各种应用场景提供了易用且全面的支持。最后这里用 sMash 的 Ajax feed API 编写一个非常有趣的实例,来展示如何用 JavaScript 统计 digg.com 上热门文章被 dig 的最大、最小以及平均次数。
首先创建 sMash 应用程序,参考“个性化 feed 内容” 部分修改配置文件增加对 zero.feed 模块的依赖。然后创建文件 public/digStatistics.html:
清单 13. HTML 文件中的 JavaScript 代码片段
function doGrouping() {
dojo.byId("loadingImg").style.display = "block";
// grouping entries with statistics of digg counts
var queryParams = {
"select": [
"digg:category/text() as atom:title",
"count($collection) as atom:summary",
"sum($collection/digg:diggCount) as digg:totalCount",
"max($collection/digg:diggCount) as digg:maxDiggCount",
"min($collection/digg:diggCount) as digg:minDiggCount",
"avg($collection/digg:diggCount) as digg:avgDiggCount"
],
"groupBy": "digg:category"
};
zero.feed.FeedFactory.fetch("http://digg.com/rss/index.xml")
.declareNamespaces({"digg":"http://digg.com/docs/diggrss/"})
.query(queryParams)
.filterByXPath("atom:summary > 1")
.loadAsXML(function(feed){
// …
});
} |
最后启动这个 sMash 应用程序,使用浏览器访问 http://localhost:8080/digStatistics.html,单击按钮“digg.com statistics”,你就会看到如图 12 的有趣的统计结果了!
如果你需要完整的演示程序代码,可以在 sMash 的演示程序 zero.flow.demo 中找到它。
图 12. 使用 Ajax feed API 创建的 digg.com 统计
结束语
通过介绍使用 WebSphere sMash 开发 REST 风格的 Web 应用程序,尤其是 sMash 针对 RSS/Atom feed 这些流行的信息聚合格式提供的各种功能和工具支持,相信读者已经对 feed 的应用和开发有了一定了解。文中例子的完整代码都可以在下面的“下载”栏目中找到,你只需要安装有 WebSphere sMash 的命令行工具即可运行他们,使用 AppBuilder 或者 Eclipse 插件可以让开发变得更轻松。
下载 | 描述 | 名字 | 大小 | 下载方法 |
|---|
| 为数据提供 feed 视图的演示 | feedview.demo-1.0.0.zip | 14 KB | HTTP |
|---|
| 个性化 feed 内容的演示 | personalfeed.demo-1.0.0.zip | 17 KB | HTTP |
|---|
| 统计 digg.com 热门文章的 dig 数量 | zero.flow.demo- 1.1.1.1.30710.zip | 140 KB | HTTP |
|---|
| 为第三方服务提供 feed 数据视图的演示 | servicefeed.demo-1.0.0.zip | 5 KB | HTTP |
|---|
| 为数据服务提供 REST 风格 API 的演示 | contact.demo-1.0.0.zip | 23 KB | HTTP |
|---|
参考资料 学习
获得产品和技术
关于作者  | |  | 朱可:从清华大学获得工学硕士学位后加入了 IBM。目前就职于 IBM 中国软件开发中心 , 是 Project Zero 团队的软件工程师,主要从事 WebSphere sMash 的产品开发工作。对 Web、Java、Linux 等技术和敏捷工程都有浓厚的兴趣。 |
对本文的评价
|