Groovy
和
Grails
简介
时间:
2006-12-26
作者:
Harshad Oak
摘要
摘要
Java Web
应用程序框架是企业
Java
得以成功的重要原因之一。人们怀疑如果没有
Apache Struts
框架
Java EE
是否能够如此成功。虽然底层编程语言很重要,但通常是框架使编程语言成为引人注目的中心的。如果您经常访问讨论论坛,就会注意到
Ruby
语言和
Ruby On Rails
框架之间也是这种情况。
Ruby
已经出现十多年了,然而只是在
Ruby On Rails
框架流行之后,开发人员才开始注意到
Ruby
语言。
诸如
Ruby
、
PHP
和
Python
之类的脚本语言最近几年越来越流行,因此,需要开发一个
Java
脚本备选语言和类似
Rails
的针对
Java
环境的框架。
Groovy
就是这个脚本语言,而
Grails
就是这个框架。
在本文中我将讨论
Groovy
的
Web
开发功能,然后继续讨论
Grails
框架。我将开发一个示例
Grails Web
应用程序,并讨论此框架的各种特性。
Groovy
是什么?
Groovy
是一种语言,其语法类似于
Java
,但比
Java
更简单。它通常被视为脚本
/
灵活
/
动态的语言,但是我不喜欢这类形容词,因为我认为它们只会令人困惑。如果说
Java
是一位明智的中年男子,那么
Groovy
就是他十几岁的儿子。
Groovy
具有父亲的许多特点,但是更为狂野且更为有趣。他们也可以很好地合作。
Groovy
的规则比
Java
少得多。例如,要在
Java
中获得标准的
"Hello World"
输出,您需要编写一个类、一个具有合适参数的主方法,等等。但是在
Groovy
中,如果不想编写所有样板代码,您可以抛开类定义和主方法,仅编写一行代码即可打印出
"Hello World"
。
以下是打印
Hello World
的文件
Hello.groovy
的内容:
println "Hello World"
Java
平台仅关心使字节码得到执行。同样,此平台不强迫您使用
Java
语言。只要提供了字节码,工作就会进行。
Groovy
代码会被编译为字节码,而对于
Java
平台来说,字节码是从
Java
代码还是
Groovy
代码生成的并没有任何区别。
以下是一个
Groovy
例子,它显示了
Groovy
对清单、映射和范围的内置支持,并证明了
Groovy
的简单性及其利用
Java
的强大功能的能力:
// Print Date
def mydate = new java.util.Date()
println mydate
//Iterate through a map
def numbersMAP = ['1':'ONE', '2':'TWO']
for (entry in numbersMAP) {
println "${entry.key} = ${entry.value}"
}
//Introducing the range
def range = 'a'..'d'
//Lists
def numberlist = [1, 2, 3, 4, 5, 6, 7, 8]
println numberlist;
println "Maximum value: ${numberlist.max()}"
请注意以上代码直接使用
java.util.Date
,对收集的内置支持减少了使用清单、映射和范围所需的代码。还有许多其他有趣的
Groovy
特性,例如闭包和简化的
XML
处理。您可以在
groovy.codehaus.org
上找到详细清单。
现在让我们来讨论如何将
Groovy
用于
Web
开发。
使用
Groovy
进行
Web
开发
大多数
Java EE
教程都从一个基本
servlet
例子开始。对于
Groovy Web
开发来说,您将从
groovlet
(在
groovy
中
servlet
的对应概念)开始。如果您在
servlet
中摆脱了类和
doXX()
方法声明,那么剩下的内容就与
groovlet
很像了。以下是一个名为
Login.groovy
的
groovlet
例子,您需要将它置于
Web
应用程序的最高级目录:
def username= request.getParameter("username")
def password= request.getParameter("password")
if (username == "java" && password == "developer") {
response.sendRedirect("home.jsp")
session = request.getSession(true);
session.setAttribute("name", username)
}
else {
println """
<h1>Login Invalid</h1>
<p>Your IP has been logged > ${request.remoteHost}</p>
"""
paramMap = request.getParameterMap()
println "<p>You Submitted:</p>"
for (entry in paramMap) {
println "${entry.key} = ${entry.value}<br/>"
}
}
您可以仅创建一个简单的
HTML
表单,然后将此表单的行为属性发送到
action="Login.groovy"
。然后将以下标签添加到
web.xml
:
<servlet>
<servlet-name>Groovy</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Groovy</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>
现在只需将要求的
Groovy jar
文件添加到
WEB-INF/lib
目录,您的
Groovy Web
应用程序就准备好在任意
Java EE
应用服务器上运行了。
您应该已经注意到代码中没有分号,而且使用了隐式变量如
request
和
response
。其他隐式变量有
context
、
application
、
session
、
out
、
sout
和
html
。
GSP
是
JSP
在
groovy
中的对应概念。您无需使用
println
生成
HTML
;只需将
Groovy
代码嵌入
HTML
页面。本文中的例子将在提到
Grails
时使用
GSP
。
请注意,因为所有代码最终都要转换为字节码,所以
groovlet
和
GSP
能够与
servlet
和
JSP
轻松协作。因此您无需区分
groovlet
和
GSP
或者
servlet
和
JSP
。
现在让我们讨论前途无量的
Grails
框架。如果成功的话,
Grails
能够极大地改变开发
Java Web
应用程序的方式。
Ruby on Rails
对
Ruby
的影响,
Grails
也能够对
Groovy
实现。
Grails
特性和架构
Grails
试图使用
Ruby On Rails
的
“
规约编程
”
(
coding by convention
)范例来降低对配置文件和其他样板代码的需求。使用
“
规约编程
”
,如果文件的名称本身就能说明此文件的用途,那么您就不需要在配置文件中再次声明这些内容了。此框架会查看文件名,并自己弄清文件用途。通过使用
“
规约编程
”
,
Grails
还将自动生成
Web
应用程序中需要的许多内容。通过使用
Grails
,您将能够在很短的时间内、以最小的复杂性使
Web
应用程序就绪。请看以下例子。
Grails
基于开源技术,例如
Spring
、
Hibernate
和
SiteMesh
。如果您已经擅长这些技术,那么这是件好事;但是如果您由于某种原因不喜欢这些技术,或者您认为不仅需要学习
Grails
,还需要学习其他三种框架,那么这就不是件好事了。虽然这些技术能够帮助
Grails
执行得更好,但是学习四种框架对于大多数人来说是一个很高的门槛。
Grails
文档目前主要关注它与
Spring
、
Hibernate
和其他程序的集成,然而我认为它需要采用相反的方法,将
Grails
推行为一个简单快速的
Web
应用程序开发框架。开发人员无需担心或考虑底层发生了什么。
幸运的是,一旦您开始使用
Grails
,您将发现
Grails
隐藏了这些框架的大多数底层复杂性。如果您忘掉在底层运行的是
Spring
、
Hibernate
和其他程序,那么事情就会变得简单。
Grails
应用程序的三个层
是:
1.
由视图和控制器组成的
Web
层
2.
由域类和服务组成的业务逻辑层
3.
由域类和数据源组成的持久层
大多数框架都有数十种特性,其中只有很少几种得到了广泛使用。对于
Grails
来说,这种关键特性是指
“
规则编程
”
(
coding by convention
)范例和构件的自动生成。
Grails
的其他特性包括对
Ajax
、验证、单元测试和功能测试的内置支持。它使用免费的开源
Canoo WebTest
项目来实现
Web
应用程序的功能测试。
Grails
还提供与
Quartz Scheduler
的集成。
现在是时候安装
Grails
框架并且编写您的第一个应用程序了。
Grails
安装
安装过程非常简单。以下是
Grails
下载页面:
http://grails.org/Download
。您可以从
http://dist.codehaus.org/grails/grails-bin-0.2.1.zip
下载
version 0.2.1
。请注意
Grails
源代码和文档作为单独的下载提供。下载
zip
文件之后,只需将其内容解压缩到一个目录即可,在我的案例中此目录是
C:\groovy\grails-0.2.1\
。
创建一个名为
GRAILS_HOME
的新环境变量,并将其值设为
C:\groovy\grails-0.2.1\
。接下来将
GRAILS_HOME\bin
添加到
PATH
环境变量。这样安装就完成了。通过在命令提示符界面中运行
grails
命令您可以检查安装是否成功。您应该获得此命令的使用信息。
既然您有了一个运行中的
Grails
安装,那么您已经为创建
Grails Web
应用程序做好了准备。
开发
Grails
应用程序:应用程序结构
多年来我一直计划开发一个可以帮助我管理衣服的应用程序
——
这个应用程序应该能够告诉我我最喜欢的
T
恤衫放在哪里、是否洗过、是否熨过,等等。总有一天我会靠销售这个应用程序挣上几百万,但是现在我将把它用作
Grails
例子。
第一步是创建一个
Grails
项目目录结构。在这一步我将在
C:\groovy\grailsapps
创建一个新目录,并在此级别打开一个命令提示符窗口。在此窗口中,执行命令
grails create-app
。要求您输入应用程序名称。输入
ClothesMgt
。
Grails
将显示它为您创建的全部目录和文件。图
1
显示了最后得到的命令结构。
图
1
:
Grails
项目目录结构
此命令将创建约
800 KB
大小的文件和目录。这里的想法是此框架遵循已经建立的
Web
应用程序开发惯例,因此它创建的文件和目录在大多数
Web
应用程序中是有用的。虽然有些人可能不喜欢这种强制使用某种结构的想法,但是这种基于惯例的自动生成正是
Grails
的
RAD
特性的基础。
如果更仔细地看一下这些目录,您就会发现存在用于诸如控制器、视图、测试、配置文件和标签库之类东西的目录。您还会发现存在一些基本
JavaScript
和
CSS
文件。那么现在应用程序的基本结构已经有了。您只需做些填空,应用程序即可就绪。
请注意自动生成目录和文件的命令是可选的。您可以手动创建全部文件和目录。如果熟悉
Apache Ant
,那么您甚至可以打开
GRAILS_HOME
目录中的
\src\grails\build.xml
文件,来仔细查看每个
Grails
命令的用途。
数据库
在此例中我将使用一个
运行于
localhost
的名为
Clothes_Grails
的
MySQL
数据库。
Grails
内置一个
HSQL
数据库,这对测试简单的应用程序或仅试用
Grails
非常有用。如果您使用
HSQL DB
,那么无需执行以下几步。我将使用
MySQL
来证明您能够非常轻松地使用
HSQL
之外的数据库。
从
http://www.mysql.com/products/connector/j/
下载
MySQL
驱动器,并将
mysql-connector-java-<version number>-stable-bin.jar
文件放置在
ClothesMgt\lib
目录中。接下来您需要编辑
ClothesMgt\grails-app\conf\ApplicationDataSource.groovy
文件。
现在此文件的内容应该类似以下内容:
class ApplicationDataSource {
boolean pooling = true
String dbCreate = "create-drop"
String url = "jdbc:mysql://localhost/Clothes_Grails"
String driverClassName = "com.mysql.jdbc.Driver"
String username = "grails"
String password = "groovy"
}
现在让我们看一下如何使用此数据库和对象关系映射。
域类
Grails
的对象关系映射
(GORM)
功能在内部使用
Hibernate 3
,但是您无需了解或更改任何
Hibernate
设置。
Grails
具有称为
“
域类
”
的东西,这些域类的对象被映射到数据库。您可以使用关系来链接域类,它们也提供用于
CRUD
(创建
/
读取
/
更新
/
删除)操作的功能非常强大的动态方法。
在此例中,我们将创建三个域类,其名称分别是
Shirt
、