Groovy轻松入门——Grails实战基础篇
在学习任何东西之前,最重要的是培养兴趣,Groovy世界最耀眼的技术之一--Grails相信大家早已耳闻,我将通过Grails实战系列文章向您展现Grails的迷人风采,使您感受到Grails的魅力,以至疯狂地爱上Grails,并坠入Groovy的爱河。学Groovy,Grails与学Java一样,在实战之前需要搭建开发环境,您可以在 Groovy轻松入门--搭建Groovy开发环境 学习到如何搭建Groovy环境,之后我会讲一下如何搭建Grails环境,然后手把手地写个Demo程序告终,我还会抽空写篇“Groovy轻松入门--Grails实战之进阶篇”一,搭建Grails环境0,下载Grails( http://dist.codehaus.org/grails/grails-bin-1.0.zip,请留意朝花夕拾——Groovy & Grails中的“最新版本”提示)并解压到自己指定位置(我的位置是D:\D\MY_DEV\grails)1,设置环境变量GRAILS_HOME(注意大写),过程与“设置环境变量GROOVY_HOME”相似2,将%GRAILS_HOME%\bin添加到环境变量path中,过程与“将GROOVY_HOME目录下的bin追加到环境变量path中”相似(如果只想进行Grails开发,可以不设GROOVY_HOME)二,创建Grails Demo程序3,打开“命令行”,选择当前目录(我的为D:\Temp\grails_apps),在黑底白字的窗口中输入“grails create-app demo”,不包括双引号“”,在您的屏幕中可以看到类似下面的输出结果:D:\_DEV\grails_apps>grails create-app demoWelcome to Grails 1.0 - http://grails.org/Licensed under Apache Standard License 2.0Grails home is set to: D:\D\MY_DEV\grails-1.0Base Directory: D:\_DEV\grails_appsEnvironment set to developmentNote: No plugin scripts foundRunning script D:\D\MY_DEV\grails-1.0\scripts\CreateApp.groovy [mkdir] Created dir: D:\_DEV\grails_apps\demo\src [mkdir] Created dir: D:\_DEV\grails_apps\demo\src\java [mkdir] Created dir: D:\_DEV\grails_apps\demo\src\groovy [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\controllers [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\services [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\domain [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\taglib [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\utils [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\views [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\views\layouts [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\i18n [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\conf [mkdir] Created dir: D:\_DEV\grails_apps\demo\test [mkdir] Created dir: D:\_DEV\grails_apps\demo\test\unit [mkdir] Created dir: D:\_DEV\grails_apps\demo\test\integration [mkdir] Created dir: D:\_DEV\grails_apps\demo\scripts [mkdir] Created dir: D:\_DEV\grails_apps\demo\web-app [mkdir] Created dir: D:\_DEV\grails_apps\demo\web-app\js [mkdir] Created dir: D:\_DEV\grails_apps\demo\web-app\css [mkdir] Created dir: D:\_DEV\grails_apps\demo\web-app\images [mkdir] Created dir: D:\_DEV\grails_apps\demo\web-app\WEB-INF\classes [mkdir] Created dir: D:\_DEV\grails_apps\demo\web-app\META-INF [mkdir] Created dir: D:\_DEV\grails_apps\demo\lib [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\conf\spring [mkdir] Created dir: D:\_DEV\grails_apps\demo\grails-app\conf\hibernate[propertyfile] Creating new property file: D:\_DEV\grails_apps\demo\application.properties [copy] Copying 2 files to D:\_DEV\grails_apps\demo [copy] Copying 2 files to D:\_DEV\grails_apps\demo\web-app\WEB-INF [copy] Copying 5 files to D:\_DEV\grails_apps\demo\web-app\WEB-INF\tld [copy] Copying 87 files to D:\_DEV\grails_apps\demo\web-app [copy] Copying 17 files to D:\_DEV\grails_apps\demo\grails-app [copy] Copying 1 file to D:\_DEV\grails_apps\demo [copy] Copying 1 file to D:\_DEV\grails_apps\demo [copy] Copying 1 file to D:\_DEV\grails_apps\demo[propertyfile] Updating property file: D:\_DEV\grails_apps\demo\application.propertiesCreated Grails Application at D:\_DEV\grails_apps/demoD:\_DEV\grails_apps>通过“grails create-app”这个命令,Grails自动帮我们创建了开发所需的工程环境。其实您现在就已经拥有了一个可运行的Web应用程序,然后进入demo目录(“cd demo”),输入“grails run-app”,回车,启动这个‘五脏俱全’的程序雏形,打开浏览器,输入 http://localhost:8080/demo ,回车,看到了吧 :) 让我们继续吧,请停止这个程序(Ctrl + C)4,在“命令行”中输入“cd demo”,回车,以进入demo目录,然后再输入“grails create-domain-class User”创建domain class即类似于pojo的pogo,它对应MVC中的Model,不过由Grails自动创建的pogo是空的,需要自己添加属性,约束(constraints)等。输出结果如下所示:D:\_DEV\grails_apps\demo>grails create-domain-class UserWelcome to Grails 1.0 - http://grails.org/Licensed under Apache Standard License 2.0Grails home is set to: D:\D\MY_DEV\grails-1.0Base Directory: D:\_DEV\grails_apps\demoEnvironment set to developmentNote: No plugin scripts foundRunning script D:\D\MY_DEV\grails-1.0\scripts\CreateDomainClass.groovy [copy] Copying 1 file to D:\_DEV\grails_apps\demo\grails-app\domainCreated for User [copy] Copying 1 file to D:\_DEV\grails_apps\demo\test\integrationCreated Tests for UserD:\_DEV\grails_apps\demo>5,进入D:\Temp\grails_apps\demo\grails-app\domain(这个目录中存放着所有的domain class),打开User.groovy,修改为如下内容:class User { String name String password String toString() { " $name : $password " } static constraints = { name(blank: false ) password(blank: false , size: 6 .. 16 ) }} contraints这个类变量是定义一些约束的,比如name不能为空白,password不能为空白而且长度在6到16之间(包括6和16)6,在“命令行”中输入“grails generate-all User”,为User产生所有CRUD操作需要的代码(如控制器UserController.groovy)和页面(如list.gsp),输出结果如下所示:D:\_DEV\grails_apps\demo>grails generate-all UserWelcome to Grails 1.0 - http://grails.org/Licensed under Apache Standard License 2.0Grails home is set to: D:\D\MY_DEV\grails-1.0Base Directory: D:\_DEV\grails_apps\demoEnvironment set to developmentNote: No plugin scripts foundRunning script D:\D\MY_DEV\grails-1.0\scripts\GenerateAll.groovy [mkdir] Created dir: D:\_DEV\grails_apps\demo\web-app\WEB-INF\lib [mkdir] Created dir: C:\Documents and Settings\Daniel\.grails\1.0\projects\demo\classes [groovyc] Compiling 7 source files to C:\Documents and Settings\Daniel\.grails\1.0\projects\demo\classes [mkdir] Created dir: C:\Documents and Settings\Daniel\.grails\1.0\projects\demo\resources\grails-app\i18n[native2ascii] Converting 10 files from D:\_DEV\grails_apps\demo\grails-app\i18n to C:\Documents and Settings\Daniel\.grails\1.0\projects\demo\resources\grails-app\i18n [copy] Copying 1 file to C:\Documents and Settings\Daniel\.grails\1.0\projects\demo\classes [copy] Copying 1 file to C:\Documents and Settings\Daniel\.grails\1.0\projects\demo\resources [copy] Copying 1 file to C:\Documents and Settings\Daniel\.grails\1.0\projects\demo[0] spring.GrailsWebApplicationContext Refreshing org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@2b2057: display name [org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@2b2057]; startup date [Tue Feb 05 23:26:45 CST 2008]; root of context hierarchy[16] spring.GrailsWebApplicationContext Bean factory for application context [org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@2b2057]: org.springframework.beans.factory.support.DefaultListableBeanFactory@eebf17Generating views for domain class User ...Generating controller for domain class User ...Finished generation for domain class UserD:\_DEV\grails_apps\demo>7,修改demo\grails-app\controllers\UserController.groovy的内容为: class UserController { def loginService // 新增的代码 def index = { redirect(action:list,params:params) } // the delete, save and update actions only accept POST requests def allowedMethods = [delete:'POST', save:'POST', update:'POST'] def list = { if(!params.max) params.max = 10 [ userList: User.list( params ) ] } def show = { def user = User.get( params.id ) if(!user) { flash.message = "User not found with id ${params.id}" redirect(action:list) } else { return [ user : user ] } } def delete = { def user = User.get( params.id ) if(user) { user.delete() flash.message = "User ${params.id} deleted" redirect(action:list) } else { flash.message = "User not found with id ${params.id}" redirect(action:list) } } def edit = { def user = User.get( params.id ) if(!user) { flash.message = "User not found with id ${params.id}" redirect(action:list) } else { return [ user : user ] } } def update = { def user = User.get( params.id ) if(user) { user.properties = params if(!user.hasErrors() && user.save()) { flash.message = "User ${params.id} updated" redirect(action:show,id:user.id) } else { render(view:'edit',model:[user:user]) } } else { flash.message = "User not found with id ${params.id}" redirect(action:edit,id:params.id) } } def create = { def user = new User() user.properties = params return ['user':user] } def save = { def user = new User(params) if(!user.hasErrors() && user.save()) { flash.message = "User ${user.id} created" redirect(action:show,id:user.id) } else { render(view:'create',model:[user:user]) } } // 新增的代码 def login = { if (request.method == 'POST') { User u = new User() u.properties = params if (!u.validate()) { render(view:'login', model:[user:u]) } if (params.name && params.password) { def user = loginService.check(u) if (user) { flash.message = "Welcome ${user.name}" render(view: "ok", model: [user: user]) } else { flash.error = "Invalid ${u.name} with ${u.password}" render(view: "login", model: [user: u]) } } else { render(view: "login", model: [user: u]) } } }}大家或许也看到了LoginService这个类,我将在后面演示创建它,这个LoginService类封装了所有登陆相关的业务逻辑,Grails会自动将其注入到UserController中8,在“命令行”中,输入“grails create-service Login”,创建LoginService.groovy,输出:D:\_DEV\grails_apps\demo>grails create-service LoginWelcome to Grails 1.0 - http://grails.org/Licensed under Apache Standard License 2.0Grails home is set to: D:\D\MY_DEV\grails-1.0Base Directory: D:\_DEV\grails_apps\demoEnvironment set to developmentNote: No plugin scripts foundRunning script D:\D\MY_DEV\grails-1.0\scripts\CreateService.groovy [copy] Copying 1 file to D:\_DEV\grails_apps\demo\grails-app\servicesCreated Service for Login [copy] Copying 1 file to D:\_DEV\grails_apps\demo\test\integrationCreated ServiceTests for LoginD:\_DEV\grails_apps\demo>9,修改demo\grails-app\services\LoginService.groovy的内容为:class LoginService { boolean transactional = true def check(User u) { def user = User.findWhere(name: u.name, password: u.password) return user }}10,在demo\grails-app\views\user目录下创建login.gsp和ok.gsp,它们对应MVC中的View,内容分别为:login.gsp (复制demo\grails-app\views\user\create.gsp的内容到login.gsp中,并修改):
Login
Name: | |
Password: |
ok.gsp:
Name: ${user?.name}
Password: ${user?.password}11,修改demo\grails-app\conf\BootStrap.groovy,初始化数据库:将一个User实例保存到数据库(grails自带hsqldb和jetty)中,内容如下:class BootStrap { def init = { servletContext -> new User(name: "demo", password: "123456").save() } def destroy = { }} 12,在“命令行”中,输入“grails run-app”,运行我们的Web应用,输出如下:D:\_DEV\grails_apps\demo>grails run-appWelcome to Grails 1.0 - http://grails.org/Licensed under Apache Standard License 2.0Grails home is set to: D:\D\MY_DEV\grails-1.0Base Directory: D:\_DEV\grails_apps\demoEnvironment set to developmentNote: No plugin scripts foundRunning script D:\D\MY_DEV\grails-1.0\scripts\RunApp.groovy [groovyc] Compiling 4 source files to C:\Documents and Settings\Daniel\.grails\1.0\projects\demo\classesRunning Grails application..2008-02-05 23:46:08.912::INFO: Logging to STDERR via org.mortbay.log.StdErrLog2008-02-05 23:46:08.066::INFO: jetty-6.1.42008-02-05 23:46:08.347::INFO: No Transaction manager found - if your webapp requires one, please configure one.2008-02-05 23:46:09.081:/demo:INFO: Set web app root system property: 'demo' = [D:\_DEV\grails_apps\demo\web-app\]2008-02-05 23:46:09.081:/demo:INFO: Initializing Log4J from [file:C:\Documents and Settings\Daniel/.grails/1.0/projects/demo/resources/log4j.properties]2008-02-05 23:46:09.113:/demo:INFO: Initializing Spring root WebApplicationContext[0] spring.GrailsWebApplicationContext Refreshing org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@5facbd: display name [org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@5facbd]; startup date [Tue Feb 05 23:46:14 CST 2008]; parent: org.springframework.web.context.support.XmlWebApplicationContext@1fef80a[0] spring.GrailsWebApplicationContext Bean factory for application context [org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@5facbd]: org.springframework.beans.factory.support.DefaultListableBeanFactory@aa4c7c2008-02-05 23:46:21.590:/demo:INFO: Initializing Spring FrameworkServlet 'grails'2008-02-05 23:46:21.871::INFO: Started SelectChannelConnector@0.0.0.0:8080Server running. Browse to http://localhost:8080/demo 13,打开浏览器,输入:http://localhost:8080/demo/user/login ,在Name处输入demo,Password处输入123456,点击‘Login’,跳转到成功页面:Welcome demoName: demoPassword: 123456如果您对Grails的工程目录不太熟悉,我这里为大家提供了一张表,详细地描述了各目录的用途:《Grails权威指南》表3-1.Grails工程目录目录名称相关描述grails-app此目录包含了Grails应用程序的核心工件(core artifact)+ conf此目录包含了诸如DevelopmentDataSource.groovy的配置文件+ controllers此目录包含了处理请求(request)的控制器(controller),Grails控制器将在第7章中进行讲解+ domain此目录包含了领域模型(domain model),领域模型将在第4章进行讲解+ i18n此目录包含了用于国际化的消息束(message bundle)(译者注:指的是properties文件,如messages.properties)+ services此目录包含了封装业务逻辑的service文件,service将在第10章中进行讲解+ taglib此目录包含了辅助页面生成的动态标签库,动态标签将在第8章中进行讲解+ views此目录包含了Groovy服务器页面(GSP)以及JSP页面+ layouts此目录包含了GSP或JSP的布局(layout),这些布局由SiteMesh提供支持,这将在第8章中进行讲解grails-test此目录包含了应用程序的单元测试hibernate此目录包含了可选的Hibernate配置文件,这将在第11章中进行讲解lib此目录包含了jar文件spring此目录包含了可选的Spring配置文件,这将在第11章中进行讲解src此目录包含了其他Groovy和Java资源+ java此目录包含了待编译的Java源文件+ groovy此目录包含了待编译的Groovy源文件web-app此目录包含了Web应用程序的资源(CSS,JavaScript等)注:Grails1.0已将hibernate和spring两个目录移到grails-app\conf目录下了,而grails-test目录也更名为test,test目录下有integration目录和unit目录,分别存放集成测试代码和单元测试代码想象一下用您平时做项目时所用的框架组合(比如SSH)来创建同样的Web应用程序,您立刻会感受,Grails让我们专注于业务逻辑,而不用浪费时间在那些scaffolding code(如配置文件)上。从今天开始,您不用再羡慕那些Ruby程序员所用的RoR了,您大可以使用Grails来高效开发Web应用。您也可以访问Grails官方网站(http://www.grails.org)进一步学习。
Groovy轻松入门——Grails实战基础篇相关推荐
- 猿创征文|MySQL入门到实战-基础篇
项目一 分析并设计学生管理数据库 主要目标是在了解用户软件操作需求的基础上,提炼.总结.归纳出对数据库的需求.主要内容,数据库的存储结构.表中数据及其依赖关系.设计方案的优化与规范.视图等其他数据库对 ...
- TCP网络编程模型从入门到实战基础篇,单服务器单个用户非并发版本
文章目录 前言 一.网络编程实践的必备基础知识 二.系统调用方法刨析 1.socket 2.bind 3.listen 4.accept 5.connect 三.实现一个简单的功能, 服务器将单客户端 ...
- Groovy轻松入门——通过与Java的比较,迅速掌握Groovy (更新于2008.10.18)
摘自: http://www.blogjava.net/BlueSUN/archive/2007/03/10/103014.html Groovy轻松入门--通过与Java的比较,迅速掌握Groovy ...
- SpringBoot2零基础到项目实战-基础篇
springboot2零基础到项目实战-基础篇 课程内容说明 课程单元 学习目标 基础篇 能够创建SpringBoot工程 基于SpringBoot实现ssm/ssmp整合 应用篇 能够掌握Sprin ...
- class括号里的object_Python入门 类class 基础篇
记住一句话:类是模板,而实例则是根据类创建的对象. 我初学时对类的理解是从类的字面上,可以片面的认为它是一个种类,它是相似特征的抽像,也就是相似的东西,可以把相似特征的事务抽象成一个类.(事务可以是具 ...
- Xamarin.Forms开发实战基础篇大学霸内部资料
Xamarin.Forms开发实战基础篇大学霸内部资料 介绍:本教程是国内第一本Xamarin.Forms开发专向教程.本教程针对Xamarin.Forms初学用户,全面细致的讲解Xmarin.For ...
- ASP.NET Google Maps Javascript API V3 实战基础篇一获取和设置事件处理程序中的属性...
ASP.NET Google Maps Javascript API V3 实战基础篇一获取和设置事件处理程序中的属性 <%@ Page Language="C#" Auto ...
- Nginx实战基础篇一 源码包编译安装部署web服务器
Nginx实战基础篇一 源码包编译安装部署web服务器 版权声明: 本文遵循"署名非商业性使用相同方式共享 2.5 中国大陆"协议 您可以自由复制.发行.展览.表演.放映.广播或通 ...
- ASP.NET Google Maps Javascript API V3 实战基础篇一检测用户位置
ASP.NET Google Maps Javascript API V3 实战基础篇一检测用户位置 对于一些基本的东西,google maps JavaScript api v3 文档已经讲解得足够 ...
最新文章
- pandas教程(一)Series与DataFrame
- 统计自然语言处理基础(一)
- 科普: 中间件底层实现的分布式协议之Raft
- 插入数据,已存在则不插入
- CloseableHttpClient加载证书来访问https网站
- vue.jsr入门_JSR-308和Checker框架为jOOQ 3.9添加了更多类型安全性
- python如何保存列表_python中数据的保存
- 【绝对原创】最新研究成果,EFS加密文件真的可以解密!各位不要放弃哈~
- 小试牛刀--编程实现获取计算机的IP地址和计算机名
- 循序渐进的手动安装k8s笔记-1
- 计算机信应用技术,计算机信息应用技术.ppt
- UE4-蓝图-角色的移动,视角控制(五)人物走动到停下过度动画
- 脚踏实地才能仰望星空
- 区块链技术在金融行业的应用与风险管理
- 产品概念之2/4:三层次理论 —— 生产者主导视角的产品概念
- C++动态开辟数组空间
- Android工具类的整理
- GitHub中Organization的Member邀请和clone代码库
- 解决Linux上steam更新游戏后导致版本不一致连接失败的问题
- 程序员去美国工作:工作在加州的华为
热门文章
- 利用压缩空气原理,VR网球拍也能模拟空气阻力
- 海思低功耗IP门铃方案(Hi3518EV200+Hi1131s+MCU+LiteOS)
- echarts 地图geo、geo3D 下穿
- 通过游戏学python_CheckIO:以游戏的形式学习Python
- android怎么处理模糊图片,Android 图片的高斯模糊处理
- Python面试题 - 基础题(一)
- python小功能 模拟下载进度条打印
- 百度业务运营部_数据分析师(产品运营)岗位要求详解(1)
- 推荐一款能支持国密SM2的浏览器——密信浏览器
- Java核心技术 国际化