最后需要做的是向未经认证的用户开放 Atom feed。调整 EntryController.groovy 中的 beforeInterceptor,如清单 20 所示:
清单 20. 向未经认证的用户开放 Atom feed
class EntryController { def beforeInterceptor = [action:this.&auth, except:["index", "list", "show", "atom"]] //SNIP } |
重新启动 Grails,当访问 http://localhost:9090/blogito/entry/atom 时,应该产生一个格式良好的 Atom feed,如清单 21 所示:
清单 21. 格式良好的 Atom feed
<feed xmlns="http://www.w3.org/2005/Atom"> <title type="text">News from Blogito.org</title> <link rel="alternate" type="text/html" href="http://blogito.org/"/> <link rel="self" type="application/atom+xml" href="http://blogito.org/entry/atom" /> <updated>2009-04-20T00:03:34-07:00</updated> <author><name>Blogito.org</name></author> <id>tag:blogito.org,2009-01-01:entry/atom</id> <generator uri="http://blogito.org" version="0.1">Hand-rolled Grails code</generator> <entry xmlns='http://www.w3.org/2005/Atom'> <author> <name>Jane Smith</name> </author> <published>2009-04-20T00:03:34-07:00</published> <updated>2009-04-20T00:03:34-07:00</updated> <link href="http://blogito.org/blog/jsmith/Testing_with_Groovy" rel="alternate" title="Testing with Groovy" type="text/html" /> <id>tag:blogito.org,2009:/blog/jsmith/Testing_with_Groovy</id> <title type="text">Testing with Groovy</title> <content type="xhtml"> <div xmlns="http://www.w3.org/1999/xhtml"> See Practically Groovy </div> </content> <!-- SNIP --> </entry> </feed> |
虽然您对 Atom 的语义可能有点陌生,但使用 Grails 生成 Atom feed 的方法应该很简单。
![]() ![]() |
验证 Atom feed
为了验证这个 feed 是格式良好的 Atom,访问 W3C 的在线 Feed Validator(见 参考资料)。如果 feed 在一个公共可访问的 URI 上,那么可以将它粘贴到主页上,并单击 Check。您的 Atom feed 是在 localhost 上运行的,所以单击 Validate by Direct Input,并粘贴 feed 的输出。结果如图 4 所示:
图 4. W3C 验证器

这里没有警告说 self 链接在提供的 URI 上不可用 — 事实显然正是如此 — 您的 Atom feed 应该被认定为是有效的、可生成的。
![]() ![]() |
添加 feed 图标
接下来再来个锦上添花,将该 feed 的链接添加到头部。可以从网上很多地方下载无处不在的 feed 图标;它是在开源 Mozilla 许可下发布的(见 参考资料)。
将该文件复制到 web-app/images 中,然后调整 grails-app/views/layouts/_header.gsp,如清单 22 所示:
清单 22. 将 feed 图标添加到头部
<div id="header"> <p><g:link class="header-main" controller="entry">Blogito</g:link></p> <p class="header-sub"> <g:link controller="entry" action="atom"> <img src="${createLinkTo( dir:'images',file:'feed-icon-28x28.png')}" alt="Subscribe" title="Subscribe"/> </g:link> A tiny little blog </p> <div id="loginHeader"> <g:loginControl /> </div> </div> |
结果应该是一个如图 5 所示的主页:
图 5. 含有 feed 图标的 Blogito 主页

![]() ![]() |
结束语
在本文中,您添加了文件上传功能,以及一个 Atom 聚合 feed。至此,Blogito 是一个可以使用的 非常小的博客服务器。它到底有多小?两个 domain 类,两个控制器,刚刚超过 250 行代码。可以输入 grails stats 进行验证。清单 23 显示了代码的行数。
清单 23. Blogito 的大小
$ grails stats +----------------------+-------+-------+ | Name | Files | LOC | +----------------------+-------+-------+ | Controllers | 2 | 127 | | Domain Classes | 2 | 34 | | Tag Libraries | 3 | 66 | | Unit Tests | 6 | 24 | | Integration Tests | 1 | 10 | +----------------------+-------+-------+ | Totals | 14 | 261 | +----------------------+-------+-------+ |
虽然这个练习占用了 4 篇文章的篇幅,但是,如果您有较扎实的 Grails 方面的应用知识,实际上它只需要一天的开发工作量。 (责任编辑:A6)