上次我们讲了RSS摘要,事实上,还有一种摘要叫Atom摘要,这种摘要主要用于国外,它是RSS的一种改良版本。关于RSS摘要的信息,网上很多,就不罗列了,大体上来讲:RSS的<channel>相当于Atom的<feed>,而RSS的<item>相当于Atom的<entry>.至于他们的细节的不同,可以参考这篇博客: http://www.ibm.com/developerworks/cn/web/wa-syndrssatom/index.html

 

理论不多说了,我想说的是,其实Apache提供了一个叫Abdera的框架,它是ATOM 联合协议(Atom Syndication)和ATOM 发布协议(ATOM Publication,简称APP)的开源实现。关于ATOM 联合协议,它主要用来定义ATOM摘要(feed)和ATOM条目(entry)的的格式,并且遵从RFC4287规范(http://www.ietf.org/rfc/rfc4287.txt),而ATOM发布协议,则是用REST的方式来对网上的ATOM文档进行维护,它主要遵从RFC5023规范(http://www.ietf.org/rfc/rfc5023.txt)

我们这个例子很简单,一是演示如何用Abdera框架创建Atom条目和Atom摘要,二是如何我们创建的条目发布到支持Atom的博客系统上。

准备工作:

我们需要下载Abdera框架:http://abdera.apache.org/#abdera.1.1.2

此外,我们必须注册一个Google账户,并且开通了Google博客系统,比如我的Google博客系统是:http://welcome2charles.blogspot.com/。国内的用户可能要×××,我是使用了vpn来演示的。

 

Part 1: Demo如何使用Abdera框架来编写Atom Entry和Atom Feed:

首先,我们编写一个工具类来专门创建Atom条目(Entry):

package com.charles.learnatom;  import java.util.Date;  import org.apache.abdera.factory.Factory; import org.apache.abdera.model.Entry; import org.apache.abdera.parser.stax.util.FOMHelper;  /**  *  * Description: 这个工具类可以用来创建Atom 记录(entry)  *  * @author charles.wang  * @created May 10, 2012 1:05:58 PM  *   */ public class AtomEntryCreator {          /**      *       * @param abderaFactory 这是abdera的文档工厂,它用来生成某个Atom 条目(Entry)      * @param updatedDate     Atom Entry的更新时间      * @param title           Atom Entry的标题      * @param author          Atom Entry的作者      * @param link            Atom Entry的链接      * @param content         Atom Entry的内容部分      * @return 由abdera工厂生成的Atom Entry      */     public static Entry createAtomEntry(             Factory abderaFactory,             Date updatedDate,             String title,             String author,             String link,             String content){                  Entry entry = abderaFactory.newEntry();         //让Feed Object Model帮你创建一个uuid         entry.setId(FOMHelper.generateUuid());         entry.setUpdated(updatedDate);         entry.setTitle(title);         entry.addAuthor(author);         entry.addLink(link);         //entry.setContent(content);         entry.setContentAsXhtml("<p>"+content+"</p>");         return entry;     }  }

 

 

然后,我们编写一个工具类来专门创建Atom 摘要(Feed):

 

package com.charles.learnatom;  import java.util.Date; import java.util.List;  import org.apache.abdera.factory.Factory; import org.apache.abdera.model.Entry; import org.apache.abdera.model.Feed; import org.apache.abdera.parser.stax.util.FOMHelper;  /**  *  * Description:这个工具类可以用来创建Atom 摘要(feed)  *  * @author charles.wang  * @created May 10, 2012 1:46:41 PM  *   */ public class AtomFeedCreator {      /**      *       * @param abderaFactory 这是abdera的文档工厂,它用来生成某个Atom 摘要(Feed)      * @param updatedDate   Atom Feed的更新时间      * @param title         Atom Feed的标题      * @param author        Atom Feed的作者      * @param links         Atom Feed中包括的所有链接      * @param entries       Atom Feed中包括的所有的条目(Entry)      * @return      */     public static Feed createAtomFeed(             Factory abderaFactory,             Date updatedDate,             String title,             String author,             List<String> links,             List<Entry> entries){                  //创建一个Atom Feed 文档         Feed feed=abderaFactory.newFeed();         //添加元信息         //让Feed Object Model帮你创建一个uuid         feed.setId(FOMHelper.generateUuid());         feed.setUpdated(updatedDate);         feed.setTitle(title);         feed.addAuthor(author);         //因为一份摘要(Feed)有可能有多个链接,所以要依次加入Feed文档中         for( String link:links){             feed.addLink(link);         }         //因为一份摘要(Feed)可能有多个条目(Entry),所以要依次加入到Feed文档中         for(Entry entry : entries){             feed.addEntry(entry);         }                  return feed;      } }

 

 

然后我们编写一个驱动类,来调用这2个方法,根据我们传入的参数来创建相应的条目和摘要,并且打印在控制台上:

 

public static void main(String[] args) throws Exception{        // TODO Auto-generated method stub                //创建一个Abdera的实例         Abdera abdera = new Abdera();        //创建一个Abdera工厂,这个工厂可以用来创建atom entry文档和atom feed文档        Factory factory = abdera.getFactory();                //创建第一个Atom Entry文档        String title1="Atom Entry 1";        String author1="Charles Wang";        String link1="http://welcome2charles.blogspot.com";        String content1="这是第一个用Apache Abdera框架创建的 Atom Entry ";        Entry entry1 = AtomEntryCreator.createAtomEntry(factory, new Date(), title1, author1, link1, content1);                //打印这个Atom Entry 文档        //entry1.writeTo(abdera.getWriterFactory().getWriter("prettyxml"),System.out);                //创建第二个Atom Entry文档        String title2="Atom Entry 2";        String author2="Charles Wang";        String link2="http://welcome2charles.blogspot.com";        String content2="这是第二个用Apache Abdera框架创建的 Atom Entry ";        Entry entry2 = AtomEntryCreator.createAtomEntry(factory, new Date(), title2, author2, link2, content2);                //创建一个Atom Feed文档,这个文档中包含上述创建的两个Atom Entry        String feedTitle="A New Created Atom Feed";        String feedAuthor="Charles Wang";        ArrayList<String> feedLinks = new ArrayList<String> ();        feedLinks.add("http://welcome2charles.blogspot.com");        feedLinks.add("http://www.blogger.com/feeds/6924231941130538538/posts/default");        ArrayList<Entry> feedEntries = new ArrayList<Entry> ();        feedEntries.add(entry1);        feedEntries.add(entry2);                Feed feed = AtomFeedCreator.createAtomFeed(factory, new Date(), feedTitle, feedAuthor, feedLinks, feedEntries);        //打印这个Atom Feed 文档,有两个参数,第一个是abdera自定义个格式化Writer,第二个是真实的输出目的地        feed.writeTo(abdera.getWriterFactory().getWriter("prettyxml"),System.out);                }

 

 

最终,我们创建的条目1样子如下:

 

<?xml version='1.0' encoding='UTF-8'?> <entry xmlns="http://www.w3.org/2005/Atom">   <id>urn:uuid:94ABFEBB6CF5417A281336630977803</id>   <updated>2012-05-10T05:45:15.224Z</updated>   <title type="text">Atom Entry 1</title>   <author>     <name>Charles Wang</name>   </author>   <link href="http://welcome2charles.blogspot.com" />   <content type="xhtml">       <div xmlns="http://www.w3.org/1999/xhtml">         <p>这是第一个用Apache Abdera框架创建的 Atom Entry </p>       </div>     </content> </entry>

 

 

而我们的Feed文件因为同时包含了条目1和条目2,所以打印出的样子如下:

 

<?xml version='1.0' encoding='UTF-8'?> <feed xmlns="http://www.w3.org/2005/Atom">   <id>urn:uuid:94ABFEBB6CF5417A281336630978024</id>   <updated>2012-05-10T06:22:58.021Z</updated>   <title type="text">A New Created Atom Feed</title>   <author>     <name>Charles Wang</name>   </author>   <link href="http://welcome2charles.blogspot.com" />   <link href="http://www.blogger.com/feeds/6924231941130538538/posts/default" />   <entry>     <id>urn:uuid:94ABFEBB6CF5417A281336630977803</id>     <updated>2012-05-10T06:22:57.677Z</updated>     <title type="text">Atom Entry 1</title>     <author>       <name>Charles Wang</name>     </author>     <link href="http://welcome2charles.blogspot.com" />     <content type="xhtml">       <div xmlns="http://www.w3.org/1999/xhtml">         <p>这是第一个用Apache Abdera框架创建的 Atom Entry </p>       </div>     </content>   </entry>   <entry>     <id>urn:uuid:94ABFEBB6CF5417A281336630978023</id>     <updated>2012-05-10T06:22:58.021Z</updated>     <title type="text">Atom Entry 2</title>     <author>       <name>Charles Wang</name>     </author>     <link href="http://welcome2charles.blogspot.com" />     <content type="xhtml">       <div xmlns="http://www.w3.org/1999/xhtml">         <p>这是第二个用Apache Abdera框架创建的 Atom Entry </p>       </div>     </content>   </entry> </feed>

 

 

Part2 :利用Abdera框架和APP(Atom Publishing Protocol)吧我们创建的条目发布到Google Blogger 上:

 

我们可以用以下的代码:

 

public static void main(String[] args) throws Exception{         //这里略去,就是我们创建的Entry1                  ...          //发表某个记录         System.out.println("开始发布条目到Google Blogger");         AbderaClient client= new AbderaClient(abdera);         //创建一个Google登录的认证信息凭证         //第一个是用户名(注册邮箱),第二个是密码,第三个是服务名(必须是blogger)         GoogleLoginAuthCredentials creds = new GoogleLoginAuthCredentials("xxx@xxx.com", "xxxxxx", "blogger");         //将凭证信息加到abdera客户端         client.addCredentials("http://www.blogger.com/home", null, "GoogleLogin", creds);                   RequestOptions options = client.getDefaultRequestOptions();         options.setUseChunked(false);         //发送包含我们文章的Entry,参数有3个,一是发送的目的地,二是发送的Entry,三是可选参数         Response response = client.post(           "http://welcome2charles.blogspot.com/feeds/posts/default",            entry1, options);                      }

这段代码中,几个参数我要说明下:

(1) GoogleLoginAuthCredentials中传入的账号密码是你的google账号的信息,而第三个参数是服务名,因为我们请求的是博客服务(blogger),所以这里必须写"blogger"。

(2) client.post()中的第一个参数,是我们要发送的目的地,它也就是我们的博客的feed目标地址,这个地址,我们可以要像下面这样获得:先注册Google Blogger,打开到首页,然后右键选择"view source",然后会看到如下的内容:

 

利用Apache Abdera 框架创建和发布Atom Entry, Atom Feed_APP

可以看到<link rel="alternate" type="application/atom+xml">这个元素就代表你页面上如何管理到Atom Feed,所以这个元素后面对应的地址(href),就是我们所需要的, 也就是应该写到client.post()的第一个参数中的。