首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

精通 Grails 创建自定义插件(1)

精通 Grails 创建自定义插件(1)

ShortenUrl 插件简介测试至上测试您的 Grails 应用程序总是很重要,在创建插件时,测试尤其重要。插件中的缺陷的负面影响可能会成倍放大,损害安装该插件的应用程序。您将看到,本文将重点关注测试。

在这个 Twitter.com 和手机消息通讯时代,许多长 URL 不能满足消息上设置的 140 个字符的限制,这是一件麻烦事!幸运的是,有几个 URL 缩短服务强烈要求作为自定义插件集成到 Grails 中。
要创建一个自定义插件,必须略微更改 Grails 例程。您必须输入 grails create-plugin(见清单 1),而不是像往常一样输入 grails create-app。(一定要在一个新的空目录中输入这个命令,而不是 在一个现有 Grails 目录中输入。本文末尾将介绍如何集成这个新插件和一个现有 Grail 应用程序)。
清单 1. 创建一个自定义插件
1
$ grails create-plugin shortenurl




生成的目录结构与一个典型的 Grails 应用程序一致。但是,根目录中有一个文件将这个项目识别为一个插件:ShortenurlGrailsPlugin.groovy。清单 2 显示了一段代码:
清单 2. 插件配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ShortenurlGrailsPlugin {
    // the plugin version
    def version = "0.1"
    // the version or versions of Grails the plugin is designed for
    def grailsVersion = "1.1.1 > *"
    // the other plugins this plugin depends on
    def dependsOn = [:]
    // resources that are excluded from plugin packaging
    def pluginExcludes = [
            "grails-app/views/error.gsp"
    ]

    // TODO Fill in these fields
    def author = "Your name"
    def authorEmail = ""
    def title = "Plugin summary/headline"
    def description = '''\\
Brief description of the plugin.
'''

    //snip
}




这个文件包含插件元数据:版本号、插件附属的 Grails 的版本号、插件附属的其他插件等。(要查看包含配置文件详细信息的在线文档,请参见 )。
如果您想允许其他开发人员从 Plugins 门户网站下载这个插件,应该填写作者信息和具有吸引力的说明。每当您将插件签入公共 Subversion 存储库,文件的内容将被读取并自动显示在 Grails Web 站点上。(要了解关于发表您的插件的更多信息,请参见 )。在本文中,这个插件将作为一个私有插件,因此,填写作者信息就不那么重要了。
即使这个 ShortenUrl 插件不需要对 ShortenurlGrailsPlugin.groovy 进行任何更改,但这并不代表您的工作已经完成了。现在目录结构已经就绪,下一步就是编写实现。
创建 TinyUrl 类TinyUrl.com 是一个流行的 URL-shortening 服务。某人提交一个长 URL 请求缩短后,它将针对后续请求在后台将其存储为一个正式的缩短 URL。例如,访问该站点,输入 http://www.grails.org/The+Plug-in+Developers+Guide,然后单击 Make TinyURL! 按钮。生成的缩短 URL — http://tinyurl.com/73495c — 是原长度的一半,如图 1 所示。
图 1. TinyURL.com 缩短一个 URL现在您了解了 TinyURL.com 的工作方式,下面可以关注如何将这个网站的底层服务和 ShortenUrl 插件集成起来了。在您的 Web 浏览器中输入以下内容:
1
http://tinyurl.com/api-create.php?url=http://www.grails.org/The+Plug-in+Developers+Guide




这个 Web 服务界面只返回指定页面的缩短的 URL,而不是 HTML。
下一步是将您的新发现封装到 Groovy 类中。这个类是一个 Plain Old Groovy Object (POGO),正如它的名称所示,它不是服务、控制器或任何其他具有特殊目的的 Grails 组件。因此,放置它的最好位置是 src/groovy。在 src/groovy 下创建一个 org/grails/shortenurl 目录,然后创建 TinyUrl.groovy 并添加清单 3 中的代码:
清单 3. TinyUrl 实用程序类
1
2
3
4
5
6
7
8
package org.grails.shortenurl

class TinyUrl{
  static String shorten(String longUrl){
    def addr = "http://tinyurl.com/api-create.php?url=${longUrl}"
    return addr.toURL().text
  }
}




插件中的包将插件的类放在一个包中是一种很好的实践,这极大地减小了与用户的 Grails 项目中的现有类造成冲突的几率。
还可以打包域类、控制器等。对于简单的项目,这种不太常见的实践会增加不必要的复杂性,但经验丰富的 Grails 开发人员非常信任这种实践。

测试 TinyUrl 类将代码用于生产前,应该进行相应的测试,不是吗?由于您要进行一个实时 Web 调用,因此这应该是一个集成测试。在 test/integration 下创建此前创建过的相同的 org/grails/shortenurl 目录结构。创建 TinyUrlTests.groovy 并添加清单 4 中的代码。(在这个简单的例子中,宣称很小的 URL 竟然比它要编码的原始 URL 还要长。这非常有趣)。
清单 4. 测试 TinyUrl 类
1
2
3
4
5
6
7
8
9
10
package org.grails.shortenurl

class TinyUrlTests extends GroovyTestCase{
  def transactional = false

  void testShorten(){   
    def shortUrl = TinyUrl.shorten("http://grails.org")
    assertEquals "http://tinyurl.com/3xfpkv", shortUrl
  }
}




注意集成测试中的 def transactional = false 这一行。如果省略这一行,您将收到令人讨厌的错误消息,如清单 5 所示。
清单 5. 测试没有设置 def transactional = false 时收到的错误消息
1
2
3
Error running integration tests: java.lang.RuntimeException:
There is no test TransactionManager defined
and integration test ${test.name} does not set transactional = false




Grails 试图在数据库事务中包含所有测试。在普通的 Grails 应用程序中,这不成问题。但是您在一个插件中而不是在应用程序中,因此您不能假定存在这样一个数据库。您可以安装 Hibernate 插件,或者按照错误消息的指示在集成测试中设置 def transactional = false。
输入 grails test-app 并验证您的测试是否通过。
我还要实现一个 URL 缩短服务,以便这个插件的用户可以选择其中一个服务。
返回列表