`
leon1509
  • 浏览: 538232 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

案例研究:利用Grails搭建Feedlr.com网站

阅读更多
原贴地址:http://www.infoq.com/cn/articles/case-study-grails-parti

作者 侯雍容 发布于 2009年2月5日 上午2时29分
社区 Ruby, Java 主题 Web框架 标签 案例研究, Grails
Feedlr和Grails
Feedlr:feed驱动的多平台微博客机器人平台

微博客是由Twitter 创造出的一种web 2.0时代的新事物。在微博客上,人们使用简短的语言随时随地的发表消息,并可以即时地受到好友的消息。由于易用,实时等特点,Twitter在06年推 出至今逐步升温,已经拥有超过300万用户。特别在08年中,Twitter一改起步阶段geek玩具的角色,明显地向主流进化。随着Twitter的兴 起,也出现了非常多其他的微博客。仅国内就有叽歪、饭否、以及做啥等等。微博客的兴起提供了一种全新的在线沟通方式。

相关厂商内容

Adobe开发者技术日,7月16日上海,免费报名!
Twitter作为微博客的 鼻祖和最成功的例子,其优秀的API接口功不可没。通过Twitter API,开发者们开发出了众多新奇又好用的Twitter第三方应用。我开发Feedlr的出发点是建立一个让用户可以自行定制feed机器人的服务,核 心功能类似Twitter上颇受欢迎的twitterfeed,并且可以同时Twitter,叽歪,饭否以及做啥共4种微博客平台。

通过 Feedlr,用户可以建立微博客广播帐号,来随时追踪自己感兴趣的RSS/Atom Feed内容。一旦有更新,Feedlr就会自动把新的内容发送到指定的微博客平台上。Feedlr上线至今,用户们建立了自定义的新闻播报机器 人,DIY的免费天气预报机器人,不同微博客之间的消息同步机器人,甚至国内地震情况实时监控机器人等等。而通过国内微博客服务的短信通知服务,以上所有 的Feed内容国内用户都可以免费在手机上通过短信接收到。

Grails框架的选择

Grails是一个崭露头角的基于 Groovy语言,运行与JVM之上,设计上类似于Rails的快速web开发框架,在08年初刚推出1.0版。通过Groovy语言和创新的架 构,Grails把成熟的企业级JEE开源组件Spring,Hibernate等巧妙地整合起来,使用类似Rails的“按约定设计”(design by convention)理念捆绑成一套完整的web开发框架。JEE开发过程的繁琐被Groovy灵活多变的动态特性和按约定设计带来的精简配置所取代, 而又保留了企业级组件在稳定和性能方面的优势,可以说是把Rails式的快速开发带给了水深火热中的JEE开发者们。我来自JEE背景,对Groovy语 言也有一定基础,选用Grails搭建Feedlr是比较自然的选择,同时也是为了在一个没有过多约束的真实项目中体验Grails的完整开发过程。

如何用Grails实现Feedlr的核心功能
Feedlr的核心功能

Feedlr的核心功能主要包括定时查询用户提供的feed的更新,把更新的feed内容发布到微博客,再加上用来增强用户体验的多处AJAX实现以及OpenID登录等。这里逐一对这些功能的实现做一下介绍。

定时查询feed更新

Feedlr 最核心的功能就是定时轮询用户提交的feed,发现新增的条目,从而通过微博客API发送到微博上去。只要使用Grails的Quartz插件就可以非常 方便的实现这一功能。Quartz是一个用途广泛的开源Java库,用于精确地控制定时任务。由于兼容Unix Cron语法,Quartz的功能非常强大。而在Grails中,Quartz是框架自带的核心插件之一,通过Quartz插件来执行定时任务非常方便。 新建一个Quartz定时任务,只需要在Grails项目根目录下执行
grails create-job
(注意:前提是需要安装Grails插件quartz)

根 据提示输入job名称,Grails就会自动在grails-app/jobs/目录下生成一个新的job程序文件。Grails job都是以XXXJob.groovy命名,存放在grails-app/jobs目录下,Grails启动时会自动遍历jobs目录,定时执行每个定 义好的job。一个job文件用来定义一种定时执行模式,通过Unix Cron语法来定义定时逻辑。例如,Feedlr用于轮询feed的job大致是这样的:
class UpdateFeedsJob {
    def feedService    
    def cronExpression = "0 * * * * ?" //每分钟执行一次 
    def execute() {    
        feedService.updateFeeds()
    }
}


Cron 表达式“0 * * * * ?”表示每分钟执行一次。需要执行的逻辑通过定义一个execute()方法来指定。其中feedService是已经定义好的用来查询feed更新的一 个Grails Service类,使用Rome来解析feed。注意此处不需要实例化feedService变量,只要通过按约定设计的规则定义需要使用的 Service的变量名,Grails会自动找到FeedService这个Service类,注入到UpdateFeedsJob中,并把 Service实例付给feedService变量,听起来很神奇吧。这样,Grails就会每分钟触发一次UpdateFeedsJob,来查询 feed更新了。

发布feed更新到微博客

目前流行的微博客API都是已REST风格设计,通过GET和POST方法来得到或者更新内容的。例如发布一条消息到Twitter,就是通过POST方法发送到Twitter指定的API地址,简化的代码实例如下:
def conn = new URL('http://twitter.com/statuses/update.xml').openConnection()
conn.setRequestProperty ('Authorization', 'Basic ' + 'username:password'.bytes.encodeBase64())
conn.requestMethod = 'POST'
conn.doOutput = true
try{
    conn.outputStream.withWriter('UTF8'){               
        it << "status=" << newMessage
    }
}catch(Exception e){
    ...
}


以上Groovy代码很清晰易读。通过Twitter RESTful API发布新消息需要使用Http Basic验证用户登录信息,所以这里按照Basic验证规范在请求中加入了验证数据。其中encodeBase64()方法是Grails提供的神奇的 动态方法,对于合适类型的对象在Grails程序中直接就可以使用这些动态方法,其他的编码方法还包括encodeAsURL()等。

Ajax

在web 2.0时代没有Ajax的网站是不完整的。幸运的是,在Grails中使用Ajax非常方便。通过Grails内建的多才多艺的render方法,就可以轻松地给前端Ajax请求返回任何形式的输出。例如,

直接返回简单的纯文本字串
class FooController{
...
    def ajaxResponse = {
        ...
        render("This is an Ajax response.")
    }


指定返回内容的格式和编码
render(text:"<xml>some xml</xml>",contentType:"text/xml",encoding:"UTF-8")

返回模板内容
render(template:"feeds", model:[feeds:feeds], contentType:"text/html", encoding:"UTF-8")


返回JSON,直接自动转换一个object为JSON
import grails.converters.*
...
def jsonObj = [object:[collection:[[name:‘value1′],[name:‘value2′]]]]
render jsonObj as JSON


返回JSON,通过JSON builder DSL直接构造JSON数据
render(contentType:‘text/json’, , encoding:'UTF-8'){
        studio(name:‘Pixar’,website:‘pixar.com’)
        films{
                film(title:‘Toy Story’,year:‘1995′)
                film(title:‘Monsters, Inc.’,year:‘2001′)
                 film(title:‘Finding Nemo’,year:‘2003′)
        }
}


OpenID支持

Feedlr支持使用OpenID登录。由于Grails社区已经提供了OpenID插件,通过Grails的插件机制,实现OpenID支持也是一件轻松的事情。

首先,安装OpenID插件,在Grails应用根目录执行命令:

grails install-plugin openid
然后,使用openid插件提供的taglib来编写openid登录表单
<openid:form success="[controller:'login',action:'openidSuccess']" error="[controller:'login',action:'openidError']">
                <openid:input size="30" value="http://" class="input-text"/>
...
</openid:form>


OpenID 插件代为处理了具体的OpenID登录验证过程,在<openid:form>中,通过success参数和error参数指定登录成功或失 败以后重定向到哪个controller action。登录成功后,就可以在controller中直接得到当前登录的openid信息。
def openid = session.openidIdentifier


当然,需要实现完整的OpenID和普通帐号的整合还有更多工作要做,包括把登录的OpenID和已有的普通帐号关联起来,从普通帐号添加OpenID信息等。这些都是需要开发者根据自己的情况自行实现的。

测试
测 试是开发一个完整项目不可缺少的部分,幸运的是Grails已经为开发者考虑到了这点,测试Grails程序也能像开发一样轻松。Grails中的测试建 立在Groovy testing的基础上,通过使用Groovy来编写JUnit测试代码,减轻程序员的负担。Grails中的测试分为unit test和integration test两种,两者的区别主要在于unit test是相对独立的测试,而integration test执行的时候Grails会按照实际运行的方式启动框架程序。建立一个unit test或者integration test各自只需要一条命令即可。
grails create-unit-test
grails create-integration-test


Grails 会自动在grails-app/test/unit或者grails-app/test/integration下面建立相应的 XXXTests.groovy文件。具体的test case定义在XXXTests.groovy里,通过定义继承groovy.util.GroovyTestCase的类来实现,这些其实都是 Groovy测试的内容,通过JUnit方式编写测试代码即可。

准备好了test case之后,Grails同样已经为你准备好的命令来自动执行测试。
grails test-app


执行这条命令,Grails就会自动按照unit test到integration test的顺序来执行定义好的所有test case,并将测试结果整理成HTML格式展现出来。test-app命令还有更多具体用法,可以参考Grails文档。

Feedlr的部署
使用Grails的开发过程是很令人感到愉快的。那么,一切都搞定以后,怎么部署呢?

Grails 文档中说明Grails经测试可以部署到大多数常用的Java应用服务器上,但是具体有关部署的资料文档比较缺乏。Feedlr选择的是Tomcat 6,相对来讲比较常用,资料也比较丰富。准备部署Grails应用的时候,首先通过Grails把项目打包成war文件。
grails prod war feedlr.war


这里,"prod"参数用来指定打包的时候使用Config.groovy里针对生产环境的配置。部署环境的配置在Config.groovy中设定,包 括"prodcution",“development"和"testing"三种,主要用于对不同环境指定不同的数据源和特定的环境变量。具体用法可以 参考Grails文档。war命令默认的打包环境就是"prod",所以次数"prod"也可以省略。如需指定其他环境只需要将"prod"替换 成"dev"或者"test"即可。

最后指定war文件的文件名是可选的。在Tomcat下如果想让应用跑在URL根路径下,可以指定文件名为ROOT.war。打包完成后,把war文件复制到Tomcat应用目录下,启动Tomcat,正常的话Grails应用就能跑起来了。

在 系统性能和伸缩性方面,我其实没有花太多力气去优化。最主要的优化工作就是在内存占用方面。Feedlr目前使用的是一台540MB内存的VPS服务器, 在初期曾使用340MB内存的配置,遇到了内存资源紧张的问题,导致JVM性能底下。由于Feedlr的特定用途,需要解析大量feed内容,所以在内存 方面要求不低。后来经过一系列的优化措施,目前在这个环境下运行的相对比较稳定了。我之前也总结过一些Grails服务器优化的经验,有兴趣的朋友可以参考我的这篇博客文章。

实际开发中的一些困难
在Feedlr的开发中,可以体会到目前阶段使用Grails进行完整Web项目开发的一些困难和问题。

开发环境的不完善

Feedlr 是在Eclipse加上Groovy插件的环境下开发的。但是这个环境目前还非常不完善,主要是Groovy插件的可用程度还比较低,而且没有 Grails支持,不支持GSP语法等,只是能够支持Groovy语言,加上Eclipse本身的强大功能,能够给开发提供一定帮助。不过好在使用 Groovy语言开发比Java要省力不少,所以不需要非常强大的IDE也可以不错的完成任务。IDE方面另外的选择主要包括IntelliJ IDEA和NetBeans。简单来讲收费的IDEA对Groovy/Grails的支持最为完整强大,但是代价也不菲。开源方面的选择,Eclipse 方面还是比刚刚开始支持Groovy的Netbeans好过不少。

Grails本身尚不够成熟

在开发过程中也遇到过若干 Grails的bug,有的bug甚至导致某功能无法正常运行。使用一个尚不成熟的框架,遇到bug也是正常的事情。解决bug的话基本上可以先到 Grails邮件列表里提问和寻找答案,需要的话提交bug报告到Grails官方JIRA,提供bug数据等待修复。不过如果遇到紧急问题,还是自己动 手更好。可以从Grails主页下载带源码的Grails安装包,就可以直接调试bug并编译修改代码,这样不用等官方发布下一个小版本就可以直接解决问 题了。在Feedlr开发过程中遇到过若干比较紧急的bug,我随着bug报告也提供过若干补丁程序,在最新的Grails 1.0中都已被集成。在这里也要建议大家在使用过程中多多提交bug报告和提供补丁程序,这是良好的参与建设开源社区的方式。

总结
要 完整地实现Feedlr显然还有很多工作要做,但Grails确实大大减轻了程序员编码工作的负荷。通过grails stats命令可以看到,除去测试代码,feedlr最终的代码规模约是1.9kloc。对于一个完整地具备了包括全文检索,RSS/Atom feed生成(Feedlr提供最新机器人服务列表的feed),Tag标签功能,OpenID+普通登录方式整合等功能的web 2.0网站来说,这确实意味着我省去了不少打字的工夫,避免了传统JEE繁琐的开发方式。

那么,Grails到底是不是JEE世界的圣杯呢?我将在本系列的下篇文章中进一步进行分析。

参考资料
Grails:http://grails.org
Grails文档:http://grails.org/doc/1.0.x/
Groovy:http://groovy.codehaus.org/
Mastering Grails系列文章:http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=mastering+grails
作者简介
侯雍容,毕业于复旦大学计算机专业,毕业后在IBM中国开发中心从事软件开发工作,目前创立了上海睿谷信息科技有限公司,从事软件开发和咨询工作。对于敏捷Web开发、动态程序语言、云计算等方面都有特别的兴趣和经验。可以从这里看到关于他的详细资料:http://www.linkedin.com/in/houyr,也可以访问他的个人博客:http://damienh.org。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家加入到InfoQ中文站用户讨论组中与我们的编辑和其他读者朋友交流。
分享到:
评论

相关推荐

    grails-1.3.0.RC2

    在研究 `grails-1.3.0.RC2` 源代码时,开发者可以深入了解Grails框架的架构,学习如何实现MVC模式,以及如何利用Groovy语言的特性来优化Web应用的开发。此外,还可以探索框架的内部工作原理,比如GORM是如何处理...

    grails-1.2.2.zip

    《Grails 1.2.2:Web开发的革命性框架》 Grails,作为一款基于Groovy语言的开源Web应用框架,自诞生以来就以其高效、简洁和强大的功能吸引了众多开发者。Grails 1.2.2是该框架的一个重要版本,它在1.x系列中扮演了...

    Grails权威指南.pdf

    《Grails权威指南》这本书是针对Grails框架的深度解析之作,旨在帮助开发者全面...通过《Grails权威指南》,开发者可以深入理解Grails框架的全貌,掌握从开发环境搭建到项目上线的全过程,提升Web应用开发效率和质量。

    grails-5.1.2.zip

    Grails 是一个基于Groovy语言的开源Web应用框架,它构建于Java平台之上,旨在简化开发过程并提高生产力。在Grails 5.1.2这个版本中,我们看到一些关键特性和改进,这些特性有助于开发者更加高效地构建动态、灵活的...

    grails-4.0.4.zip

    Grails是一种基于Groovy语言的开源Web应用框架,它构建在Spring Boot之上,提供了一种高效、简洁的方式来开发企业级Java应用。Grails 4.0.4是该框架的一个稳定版本,它包含了多项改进和优化,旨在提高开发者的生产力...

    grails-2.4.4.zip

    Grails 2.4.4 是一个基于Java的开源Web应用框架,它利用Groovy语言的强大特性,为开发者提供了一种高效、灵活的开发环境。这个压缩包“grails-2.4.4.zip”包含了完整的Grails 2.4.4版本,使得开发者可以直接将其集成...

    Grails_Portal.pdf

    - **优势**:利用Grails Portal框架可以显著提升Web应用程序的开发效率和用户体验。 - **步骤**: - 安装和配置Grails环境。 - 创建新的Grails项目并添加必要的插件。 - 设计和实现门户布局及功能。 - 集成外部...

    Getting-Started-with-Grails-Chinese.rar_Getting Started_grails

    《Getting Started with Grails》是一本面向初学者的指南,主要介绍了Grails这一现代Web...通过阅读《Getting Started with Grails》中文版,中国开发者将能更好地利用Grails这一强大框架,构建高效、可扩展的Web应用。

    The.Definitive.Guide.to.Grails.Second.Edition.2009

    5. **案例研究篇**:通过具体案例分析,展示如何运用Grails解决实际问题。 ### Groovy语言基础 由于Grails是基于Groovy语言构建的,因此对于初学者来说,掌握一定的Groovy基础知识至关重要。这包括: - **语法...

    Apress.Beginning.Groovy.and.Grails.From.Novice.to.Professional.Jun.2008

    《Apress.Beginning.Groovy.and.Grails.From.Novice.to.Professional.Jun.2008》这本书深入浅出地介绍了Groovy语言和Grails框架,旨在帮助初学者快速掌握这两项技术并转化为专业人士。Groovy和Grails是Java生态中的...

    Grails.2.A.Quick-Start.Guide.pdf

    2. **环境搭建与配置**:详细介绍如何设置开发环境,包括安装Grails、配置IDE(如IntelliJ IDEA或Eclipse)等,确保读者能够顺利开始项目开发。 3. **项目迭代开发**:通过一个具体案例,从零开始构建一个完整的...

    grails-2.3.6.zip

    Grails是一种基于Groovy语言的开源Web应用框架,它构建在Spring Boot之上,旨在提高开发者的生产力和灵活性。Grails 2.3.6是该框架的一个特定版本,发布于2014年,提供了许多改进和新特性,旨在优化开发流程。 1. *...

    Groovy&Grails - 指南.ppt

    Grails 利用 Groovy 提供了一个高效且灵活的 Web 开发框架,减少了重复代码,提高了开发速度。与 Java 相比,Groovy 更加简洁,而与 Ruby on Rails 相比,Grails 更加适合已经在 Java 生态系统中工作的开发者,因为...

    Grails完全入门.pdf

    - **下载与解压**:从官方网站(http://grails.org)下载最新版本的Grails,解压至指定目录。 - **环境变量设置**:设置`GRAILS_HOME`为Grails的解压目录,并在系统环境变量`path`中添加`grails`的`bin`目录。 - **...

    Grails基础教程.pdf

    - 快速开发:Grails提供了丰富的脚手架功能,可以帮助开发者快速搭建应用程序的基础结构。 - 灵活性:支持多种数据库和前端技术的选择,可以根据项目需求灵活配置。 - 生产效率高:得益于Groovy语言的强大特性和...

    grails使用freemarker.rar

    标题中的“grails使用freemarker.rar”表明这是一个关于如何在Grails框架中应用FreeMarker模板引擎的资源包。FreeMarker是一个开源的、基于Java的模板引擎,它用于生成动态HTML或其他格式的文本,比如XML、PDF等。...

Global site tag (gtag.js) - Google Analytics