grails使用经验笔记

grails 使用需要知道和注意的tips:

1- gsp中的注释,如果是中文的话,在其后多加一个空格,可以避免gsp编译时的跟中文字节有关系的错误。

2- 服务类必须以Service结尾,它的运行时单件模式,默认开启事务,如果没有用到数据库事务,最好关闭事务,避免数据库连接占用过多。

3- 当域类很多时,可以在DataSource文件中进行修改,dbCreate=“none”。

4- grails同类工件的类名称不能重名,即使包名称不一样,类名称相同,这种情况也是不行,在grails内部会解析出现问题。

5- 服务类不要太多,比较耗内存,Grails启动时,初始化也慢

6- 修改BuildConfig.groovy,把相关的配置在打包war时就复制到指定的位置

 grails.war.resources = { stagingDir, args ->
    copy(todir:"${stagingDir}/WEB-INF/classes/config/", overwrite:true){fileset(dir:"config")}
    copy(todir:"${stagingDir}/WEB-INF/classes/projectconfig/", overwrite:true){fileset(dir:"projectconfig")}
}

7- layout应用与搜索顺序:

    1)、gsp模板文件里指定的layout 比如:<meta name="layout" content="main" />

    2)、在控制器里指定的layout 比如:static layout = 'main'

    3)、layouts/{ControlerName}/{ActionName}.gsp

    4)、layouts/{ControlerName}.gsp

    5)、layouts/application.gsp

8- 获取所有的服务类:grailsApplication.getArtefacts('Service')

9- 在Groovy源包里的类,如果设计成需要被继承的,那边不能放在默认包下,必须有包名称

10- grails由于域类、服务类多、加载的类多等关系,比较占perm内存,经常会内存溢出,需要修改jvm的 perm内存配置。

    tomcat操作如下:需要在bin/catalina.sh (catalina.bat windows平台) 调整一下jvm的内存设置,即在注释后面加上下面一句话,该配置内存量大小,根据实际来调整

    catalina.bat:

    set JAVA_OPTS=-Xms128m -Xmx1300m -XX:PermSize=128m -XX:MaxPermSize=500m

    catalina.sh:

    JAVA_OPTS='-Xms128m -Xmx1300m -XX:PermSize=128m -XX:MaxPermSize=500m'

11- 升级Grails版本时,可能出现一些插件升级不了,删除grails的项目缓存就可以,一般在用户目录的.grails/projects

12- 用GORM批量(大量)维护数据时,性能相对与grovy.sql.Sql, jdbc 等慢很多。

     如果是主子表的话,用域类.addXXX(),GORM性能会急剧下降(不执行.save, )。

     建议用grovy.sql.Sql,  jdbc,直接数据库存储过程等高效方法。

13- 在Web服务器里部署多个Grails应用时,无法reload。 可以用 取消部署,再部署 操作来代替。

14- src/groovy使用服务类

import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
 
def ctx = AH.application.mainContext
def authService=ctx.authService

15- 获取网站根目录的绝对路径:org.codehaus.groovy.grails.web.context.ServletContextHolder.servletContext.getRealPath('/')

16- Groovy转化成接口几种方式:

    a)、闭包方式:{} as 接口

    b)、Map方式:[方法1名称:闭包, 方法2名称:闭包] as 接口

17- controller里的render使用经验:

    1)、response.setStatus(304) 之后还需要  render '' //此处必须写render 否则网页会出错。建议使用 render status:304

    2)、在action闭包里调用了response.outputStream,那么默认的contentType='text/html'的属性会被去掉,需要再设置,但不能仍然为'text/html',

    如果需要一定要设置contentType='text/html',建议不要使用response.outputStream,可以直接用 render text:content 或 render content。

    3)、在render 内容字符串变量。在内容字符串变量里如果还有存在 <meta name="layout" content="main_crs"/> 的布局,依然有效。

    4)、render 二进制类型的文件

def getbin = {
response.contentType = 'application/octet-stream'
File file = new File('./Discipline.pdf')
file.withInputStream {  response.outputStream << it }
//render(contentType:'text/xml', text: file.text)
}

18- DataSource.groovy 经验:

    1)、pooled=true //Grails用户手册记载默认值为true,通过测试证明实际的默认值为false,用户手册此处有描述错误

    2)、在dataSource闭包里使用dbcp优化配置如下:

//以下是 dbcp 重要配置
properties { 
    //针对数据库,不能数据库可能需要做一下调整(默认:空)。经过测试好像没有影响,都会检测数据库链接是否有效
    //validationQuery = 'select 1' 
    initialSize = 5 //初始化连接(默认:0) 
    maxIdle=20 //最大空闲连接(默认:8)
    minIdle=5 //最小空闲连接(默认:0)
    maxActive=20 //最大连接数量 (默认:8)
    logAbandoned=true //是否在自动回收超时连接的时候,打印连接的超时错误(默认:false)
    removeAbandoned=true //是否自动回收超时连接(默认:false)
    //超时时间(以秒数为单位)
    //设置超时时间有一个要注意的地方,超时时间=现在的时间-程序中创建Connection的时间,如果maxActive比较大,比如超过100,那么removeAbandonedTimeout可以设置长一点比如180,也就是三分钟无响应的连接进行回收,当然应用的不同设置长度也不同。
    removeAbandonedTimeout=180 //(默认:300)
    maxWait=5000 //超时等待时间以毫秒为单位,maxWait代表当Connection用尽了,多久之后进行回收丢失连接(默认:空)
}

    3)、在pool=true的情况下才能配置上面 dbcp优化配置properties,否则启动Grails程序就会报错。即使用properties必须启用了数据库连接池pool=true,从此处也证明了第1)点。

    4)、在配置了DataSource.groovy后,在服务类里可能会切入数据库事务,未证实。

    5)、bean名称为dataSource的,是已经切入了事务,如果需要原始的,使用bean名称 dataSourceUnproxied。

    6)、最好将数据源配置放在外部文件中,这样可以避免因为数据源的改变而重新打包的问题。

19- XML使用经验:

    1)、XmlSlurper实例的parse(路径),而路径在windows上类似D:\\test/route.xml 会报错误:

    java.net.MalformedURLException: unknown protocol: d

    建议可以写成parse(new File('D:\\test/route.xml'))

    2)、GPathResult类型实际存在attributes()方法,但在api doc里没有,不影响使用

20- Grails使用JSON经验

    1)、List、Map可以用as JSON 转成 json格式

    2)、下面多种方法输出JSON格式

def json  = {
    def data2 = "[[id:1,name:'yang'],[id:2,name:'gang']]"
    def data = [[id:1,name:'yang',date:new Date()],[id:2,name:'gang',date:new Date()]]
    println data
    //方法1  
    //  render (contentType:'text/json'){
    //   //[[id:1,name:'yang'],[id:2,name:'gang']]
    //   data
    //  }
    
    def jsonFile = new File(baseDir, 'states.json') //states.json为utf-8无BOM格式,内容里有中文,下面各种方法测试都没有乱码
    println jsonFile.text
    def j = JSON.parse(jsonFile.text)
    //render (contentType:'text/json',text:jsonFile.text)//方法2
    //render (contentType:'text/json',text:data2) //方法3
    //render (contentType:'text/json',text:data as JSON) //方法4
    //render (contentType:'text/json',text:getMap() as JSON) //方法5
    //render data as JSON //方法5
    //render JSON.parse(data2) //方法6
    //render j //方法7 ontentType:'text/html'
    render contentType:'text/json',text:j //方法8
}

def getMap={
  [
    identifier:"abbreviation",
    label: "name",
    items: [
      [name:"Alabama测试2", label:"<img width='97px' height='127px' src='images/Alabama.jpg'/>Alabama",abbreviation:"AL"],
      [name:"Alaska", label:"Alaska",abbreviation:"AK"],
    ]
  ]
}


 


你可能感兴趣的:(service,controller,domain,grails)