浏览 2455 次
锁定老帖子 主题:Groovy和Grails介绍(2)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-02-18
Grails具有一个内置Resin服务器,您可使用grails run-app 命令运行应用程序。此命令会将应用程序部署到Resin服务器并启动服务器。因此您现在可以在http://localhost:8080/ClothesMgt 访问此应用程序。您还可以同样轻松地将应用程序部署到任意JavaEE服务器。我尝试将它部署到Tomcat。要实现此操作,我所需要做的是运行grails war 命令,将生成的war文件复制到Tomcat中的webapps目录! 在此案例中生成的war文件的名称为 ClothesMgt.war。一旦部署到Tomcat,您就应该能够在http://localhost:8080/ClothesMgt/ 上访问它,并看到如图2所示的屏幕。 Groovy和Grails简介图-2 图2:Grails 应用程序 通过此应用程序,能够获得Shirt、Trouser和Cabinet的全部 CRUD功能。可以显示衣橱的全部数据、向衣橱添加新衬衫和裤子、编辑它们的值和删除记录——实现这些操作都无需编写任何业务逻辑、视图或数据访问代码。仅在几分钟内您就在JavaEE服务器上部署好了一个合适的Web应用程序。很酷吧?! 让我们更进一步来定制Grails。 创建自定义控制器 我现在将把新功能和页面添加到Web应用程序,同时重用已经存在的域类。shirt/list 和 trouser/list 会分别显示衬衫和裤子的清单,现在让我们添加一个新的显示,来同时显示衬衫和裤子的清单。要创建一个新的显示,您需要一个新的控制器和视图。 使用 generate-controller 和 generate-views 命令,可以轻松实现使用域类自动生成视图和控制器。然而,在此案例中我希望创建一个与域类不直接关联的控制器。因此我将使用grails create-controller命令。当被提示输入控制器名称时,声明Display。Grails将在grails- app/controllers/ 目录创建一个名为DisplayController.groovy 的控制器,在grails-tests 目录创建一个测试套件。如清单5所示编辑控制器。 清单5:DisplayController.groovy class DisplayController { def index = {redirect(action:list,params:params)} def list = { params['max'] = 10 return [ shirtList: Shirt.list( params ), trouserList: Trouser.list( params )] } } index 闭包将请求重定向到清单。在list 闭包中我将最大参数设为10,然后使用动态方法Shirt.list 和 Trouser.list。然后返回Groovy Map,它有两个清单——衬衫清单和裤子清单。 作为Java开发人员,当看到Shirt.list()时会自然认为是在Shirt 域类中的list 方法。然而,如果打开Shirt.groovy,会发现并没有此方法。对于Java开发人员来说,不了解Groovy的特性就使用Grails不仅是令人困惑的,而且是死胡同。动态方法是Grails的特殊特性,它是构建于Groovy语言的一个非常特殊的特性元对象协议 (MOP)之上的。如此证明可以使用动态方法查询域类。因此,在控制器中,您将注意到在域类上调用的方法似乎在域类中不存在。您可以在这里阅读关于使用动态方法查询的更多信息。可以在这里找到对Grails控制器和域类中可用的动态方法的参考资料。 既然控制器能够处理请求、获取清单并转发到视图,我需要创建相应视图。 创建自定义视图 当创建控制器时,Grails还在grails-app\views 目录创建了一个新的显示目录,并将以下映射添加到web.xml 文件中。 <servlet-mapping> <servlet-name>grails</servlet-name> <url-pattern>/display/*</url-pattern> </servlet-mapping> 目前Grails有一个generate-views 命令,此命令能够生成基于域类的视图,然而没有能够自动生成视图的create-view 命令。请看图3中的例子。 Groovy和Grails简介图-3 图3:一个显示Trousers的默认视图 因为我希望创建一个独立于域类的视图,所以让我们手动创建视图文件。在目录grails-app\views\display\中,创建一个名为 list.gsp的文件,如清单6所示。 清单6:list.gsp <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>Display Shirt And Trouser List</title> <link rel="stylesheet" href="${createLinkTo(dir:'css',file:'main.css')}"></link> </head> <body> <div class="nav"> <span class="menuButton"><a href="${createLinkTo(dir:'')}">Home</a></span> </div> <div class="body"> <h1>Shirt List</h1> <table> <tr> <th>Id</th><th>Cabinet</th> <th>Color</th><th>Name</th> </tr> <g:each in="${shirtList}"> <tr> <td>${it.id}</td> <td>${it.cabinet.name}</td> <td>${it.color}</td> <td>${it.name}</td> </tr> </g:each> </table> <h1>Trouser List</h1> <table> <tr> <th>Id</th> <th>Cabinet</th> <th>Color</th> <th>Name</th> </tr> <g:each in="${trouserList}"> <tr> <td>${it.id}</td> <td>${it.cabinet.name}</td> <td>${it.color}</td> <td>${it.name}</td> </tr> </g:each> </table> </div> </body> </html> 与我之前使用的方式类似,您现在也可以使用run-app 命令运行应用程序,或者创建一个war文件并将其部署到Tomcat。您应该在http://localhost:8080/ClothesMgt/display/下看到新的视图,如图4所示。 Groovy和Grails简介图-4 图4:新创建的列出衬衫和裤子清单的视图 现在让我们快速讨论一下Grails服务。 服务 如果您想知道如何分开业务逻辑以及放置业务逻辑的位置,答案在Grails 服务中。服务以SomeNameService.groovy 格式命名,且被置于 /grails-app/services/目录。服务可利用依赖注入特性,您能够轻松地从控制器内部调用这些服务。 让我们来看一个使用服务的例子。首先,使用create-service 命令创建新服务。运行此命令并命名服务Order。Grails将创建两个文件——grails-app/services /OrderService.groovy 和 grails-tests/OrderTests.groovy。 现在编辑OrderService.groovy,如清单7所示。当引入新的orderGoods() 方法时会自动生成serviceMethod() 。 清单7:OrderService.groovy class OrderService { boolean transactional = true def serviceMethod() { // TODO } def orderGoods() { return "Order Placed - New shirts and trousers \ will be sent shortly." } } 现在编辑DisplayController,如清单8所示。引入使用OrderService的重排闭包。请注意服务将由Groovy注入。 清单8:DisplayController.groovy class DisplayController { OrderService orderService def index = {redirect(action:list,params:params)} def list = { params['max'] = 10 return [ shirtList: Shirt.list( params ) , trouserList: Trouser.list( params )] } def reorder = { render(orderService.orderGoods()) } } 现在当您访问URL http://localhost:8080/ClothesMgt/display/reorder时,重排闭包将调用 OrderService,响应会被发回到浏览器。您能够以类似方式将全部业务逻辑移入服务,然后使用Grails的注入功能非常轻松地使用它们。 动态方法和属性 正如之前提到的,域类没有能够从数据库获取数据或更新/删除现有数据的任何方法,例如find()、 findAll() 或 save() 。在控制器中您也没有编写诸如 redirect() 或 render() 之类的方法。但是域类和控制器有它们的计划目的,且允许所有要求的操作。原因是Grails中动态方法和属性的存在。动态方法被动态添加到类,就好像功能是在程序中编译的一样。 这些是可用的方法和属性,无需编写。这些动态方法涵盖了大多数Web应用程序开发中会碰到的常见情况。对于域类来说,存在诸如find()、findAll()、list()、executeQuery()、save()和 delete()之类的动态方法。控制器具有诸如session、request和response之类的动态属性,以及诸如chain()、 render()和 redirect()之类的方法。要真正利用Grails的强大功能,您需要了解所有这些动态方法和属性的功能。 顺便介绍一下:自动重载和@Property Grails的一个重要特性是能够在开发过程中进行了更改时自动重载文件。因此只需编辑和保存gsp文件,就会自动重载新文件。然而这里创建的类似OrderService 的事务服务不会被重载。您会在服务器控制台看到以下消息"[groovy] Cannot reload class [class OrderService] reloading of transactional service classes is not currently possible. Set class to non-transactional first. "。 Grails的自动重载功能会为您节省许多时间,您就无需浪费时间来重启服务器了。我碰到过一些Grails不能自动重载的案例,例如将一个jsp文件重命名到gsp。然而,Grails的这项功能有望在未来版本中得到进一步改进。 在Groovy JSR 06 的之前版本中,您必须使用@Property 来定义Groovy中的新属性。因此您会在线看到许多使用@Property的旧的Groovy例子。然而请注意,@Property已经从Groovy JSR 06中移除,在Grails 0.2和之后的版本中也不会再需要它。请参阅@Property 建议来获得更多细节。 结束语 在本文中,我介绍了Grails框架的基本特性,并使用Grails创建了一个应用程序。Groovy和Grails最大的好处是一切都运行在优秀的旧Java和Java EE上——因此您能够使用Groovy和Grails的RAD特性快速开发应用程序,然后将应用程序部署到可靠的Java EE服务器上。考虑到关于Ruby和Rails的宣传噪音,显然需要一个Java备选方案。Groovy和Grails看起来非常适合这个角色。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |