1.Default Action
Controller 默认Action为 index 可以修改为其它:
static defaultAction = "list"
2.Interceptors
Before Advice
def beforeInterceptor = {
log.trace("Executing action $actionName with params $params")
}
After Advice
def afterInterceptor = { model ->
log.trace("Executed $actionName which resulted in model: $model")
}
3.Scoped
Controller 默认scope 为 prototype ,可以修改为session ,singleton
在Controller中
static scope = "singleton"
全局设置 (Config.groovy )
grails.controllers.defaultScope = "singleton"
4.Data Binding 安全问题解决方案
只绑定指定域
def p = Person.get(1)
p.properties['firstName','lastName'] = params
排除域
def p = new Person()
bindData(p, params, [exclude: 'dateOfBirth'])
Bindable Constraint
class User {
/* userName and salary would be bindable by default */
String userName
BigDecimal salary
/* group and numberOfActiveGroups would not be bindable by default */
def group
transient int numberOfActiveGroups
static constraints = {
salary bindable: false
group bindable: true
}
}
5.渲染 JSON 数组用 array
def list() {
def results = Book.list()
render(contentType: "text/json") {
books = array {
for (b in results) {
book title: b.title
}
}
}
}
输出如下:
[
{title:"The Stand"},
{title:"The Shining"}
]
6.Type Conversion Methods (int,boolean, long, char, short,date)
def total = params.int('total')
def total = params.int('total', 42) // total 为空的时候 为42
def date = params.date('date','yyyy-MM-dd')
处理多值情况
for (name in params.list('name')) {
println name
}
7.Binary Response
def createZip() {
byte[] zip = ... // create the zip from some source
render file: zip
}
8.处理重复表单提交
view
<g:form useToken="true" ...>
controller
withForm {
// good request
}.invalidToken {
// bad request
}
9.用 forward 避免 HTTP redirect
forward action: "show"
forward controller: "book", action: "list"
forward action: "show", id: 4, params: [author: "Stephen King"]
forward controller: "book", action: "show"
10.获取/WEB-INF下 资源
def doSomething() {
def input
try {
input = servletContext.getResourceAsStream("/WEB-INF/myscript.groovy")
def result = new GroovyShell().evaluate(input.text)
render result
}
finally {
input.close()
}
}