【转载】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 demo

Welcome to Grails 1.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\D\MY_DEV\grails-1.0

Base Directory: D:\_DEV\grails_apps
Environment set to development
Note: No plugin scripts found
Running 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.properties
Created Grails Application at D:\_DEV\grails_apps/demo
D:\_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 User

Welcome to Grails 1.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\D\MY_DEV\grails-1.0

Base Directory: D:\_DEV\grails_apps\demo
Environment set to development
Note: No plugin scripts found
Running script D:\D\MY_DEV\grails-1.0\scripts\CreateDomainClass.groovy
     [copy] Copying 1 file to D:\_DEV\grails_apps\demo\grails-app\domain
Created  for User
     [copy] Copying 1 file to D:\_DEV\grails_apps\demo\test\integration
Created Tests for User
D:\_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 User

Welcome to Grails 1.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\D\MY_DEV\grails-1.0

Base Directory: D:\_DEV\grails_apps\demo
Environment set to development
Note: No plugin scripts found
Running 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\re
sources\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 hierarch
y
[16] spring.GrailsWebApplicationContext Bean factory for application context [org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationConte
xt@2b2057]: org.springframework.beans.factory.support.DefaultListableBeanFactory@eebf17
Generating views for domain class User ...
Generating controller for domain class User ...
Finished generation for domain class User
D:\_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 Login

Welcome to Grails 1.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\D\MY_DEV\grails-1.0

Base Directory: D:\_DEV\grails_apps\demo
Environment set to development
Note: No plugin scripts found
Running script D:\D\MY_DEV\grails-1.0\scripts\CreateService.groovy
     [copy] Copying 1 file to D:\_DEV\grails_apps\demo\grails-app\services
Created Service for Login
     [copy] Copying 1 file to D:\_DEV\grails_apps\demo\test\integration
Created ServiceTests for Login
D:\_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中,并修改):

 



< html >
    
< head >
        
< meta  http-equiv ="Content-Type"  content ="text/html; charset=UTF-8" />
        
< meta  name ="layout"  content ="main"   />
        
<!--  将Create User修改为Login  -->
        
< title > Login </ title >          
    
</ head >
    
< body >
        
< div  class ="nav" >
            
< span  class ="menuButton" >< class ="home"  href ="${createLinkTo(dir:'')}" > Home </ a ></ span >
            
< span  class ="menuButton" >< g:link  class ="list"  action ="list" > User List </ g:link ></ span >
        
</ div >
        
< div  class ="body" >
            
<!--  将Create User修改为Login  -->
            
< h1 > Login </ h1 >
            
<!--  将flash.message修改为flash.error  -->
            
< g:if  test ="${flash.error}" >
            
<!--  将class="message"修改为class="errors", 将flash.message修改为flash.error  -->
            
< div  class ="errors" > ${flash.error} </ div >
            
</ g:if >
            
< g:hasErrors  bean ="${user}" >
            
< div  class ="errors" >
                
< g:renderErrors  bean ="${user}"  as ="list"   />
            
</ div >
            
</ g:hasErrors >
            
            
<!--  将action="save"修改为action="login"  -->
            
< g:form  action ="login"  method ="post"   >
                
< div  class ="dialog" >
                    
< table >
                        
< tbody >
                        
                            
< tr  class ="prop" >
                                
< td  valign ="top"  class ="name" >
                                    
< label  for ="name" > Name: </ label >
                                
</ td >
                                
< td  valign ="top"  class ="value ${hasErrors(bean:user,field:'name','errors')}" >
                                    
< input  type ="text"  id ="name"  name ="name"  value ="${fieldValue(bean:user,field:'name')}" />
                                
</ td >
                            
</ tr >  
                        
                            
< tr  class ="prop" >
                                
< td  valign ="top"  class ="name" >
                                    
< label  for ="password" > Password: </ label >
                                
</ td >
                                
< td  valign ="top"  class ="value ${hasErrors(bean:user,field:'password','errors')}" >
                                    
< input  type ="text"  maxlength ="16"  id ="password"  name ="password"  value ="${fieldValue(bean:user,field:'password')}" />
                                
</ td >
                            
</ tr >  
                        
                        
</ tbody >
                    
</ table >
                
</ div >
                
< div  class ="buttons" >
                    
<!--  将value="Create"修改为value="Login"  -->
                    
< span  class ="button" >< input  class ="save"  type ="submit"  value ="Login"   /></ span >
                
</ div >
            
</ g:form >
        
</ div >
    
</ body >
</ html >

ok.gsp:

< g:if  test ="${flash.message}" >
    
< div  class ="message" > ${flash.message} </ div >
</ g:if >

Name: ${user?.name}   
< br >
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-app

Welcome to Grails 1.0 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: D:\D\MY_DEV\grails-1.0

Base Directory: D:\_DEV\grails_apps\demo
Environment set to development
Note: No plugin scripts found
Running 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\classes
Running Grails application..
2008-02-05 23:46:08.912::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
2008-02-05 23:46:08.066::INFO:  jetty-6.1.4
2008-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.pro
perties]
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.springframew
ork.web.context.support.XmlWebApplicationContext@1fef80a
[0] spring.GrailsWebApplicationContext Bean factory for application context [org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContex
t@5facbd]: org.springframework.beans.factory.support.DefaultListableBeanFactory@aa4c7c
2008-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:8080
Server running. Browse to http://localhost:8080/demo

 
13,打开浏览器,输入: http://localhost:8080/demo/user/login  ,在Name处输入demo,Password处输入123456,点击‘Login’,跳转到成功页面:
Welcome demo
Name: demo
Password: 123456

如果您对Grails的工程目录不太熟悉,我这里为大家提供了一张表,详细地描述了各目录的用途:

《Grails权威指南》3-1.Grails工程目录

目录名称

相关描述

grails-app

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值