拦截器(Interceptors)与过滤器(Filters)
在Grails3.0之前有过滤器(Filters)的概念,过滤器(Filters)虽在3.0之后仍能够继续使用(向后兼容),但这仍是过时的写法,不推荐使用,可用拦截器(Interceptors)替代。
拦截器的创建方法:
grails create-interceptor MyInterceptor
文件所在位置:
grails-app/controllers/MyInterceptor.groovy
class MyInterceptor {
boolean before() { true }
boolean after() { true }
void afterView() {
// no-op
}
}
##################
拦截器的定义:与控制器名称相同的拦截器,就是此控制器的拦截器。例如,如果你有一个拦截器BookInterceptor,然后所有对BookController中方法action的请求的行为,都将会触发拦截器。
在一个拦截器中,通常有三种方式来来拦截请求:
/**
* 在访问方法Action之前执行
*
* @return 是否继续访问方法Action,true或false
*/
boolean before() { true }
/**
* 方法Action执行后,视图View渲染前执行
*
* @return true,继续视图渲染,false进行别的操作
*/
boolean after() { true }
/**
* 视图渲染完成后执行
*/
void afterView() {}
##################
before()方法可以取消Action方法的执行(权限验证),只需return false
after()方法可以用于修改视图及模型,如:
boolean after() {
model.hello = "world" // 向model中添加一个属性,属性名为'foo',属性值是'bar'
view = 'help' // 使用'help'视图对数据进行渲染
true
}
afterView()方法,视图渲染完成后执行,可用于处理异常。
##################
匹配所有控制器的方法(matchAll):
class AuthInterceptor {
AuthInterceptor() {
matchAll().excludes(controller:"login")
}
boolean before() {
// perform authentication
}
}
matchAll匹配所有控制器,excludes,不包括什么什么
##################
匹配部分控制器的方法:
class LoggingInterceptor {
LoggingInterceptor() {
match(controller:"book", action:"show") // Book控制器(BookController)的show方法(action)被调用时触发
match(controller: ~/(author|publisher)/) // 正则表达式,控制器是AuthorController或PublisherController时触发
}
boolean before() {
…
}
}
##################
Grails中的一些常用关键字:
namespace - 控制器的命名空间
controller - 控制器名称
action - 方法名称
method - HTTP方法类型
uri - 请求的URI地址. 如果这个参数被使用,那么其余参数都将失效,仅有这个参数有效.
##################
logger 'grails.artefact.Interceptor', DEBUG, ['STDOUT'], false
#################
内容协商:
在开始处理内容协商前,你必须告诉Grails希望支持什么类型的数据。默认情况下,这些数据类型应在grails-app/conf/application.yml中的grails.mime.types中来定义。
grails:
mime:
types:
all: '*/*'
atom: application/atom+xml
css: text/css
csv: text/csv
form: application/x-www-form-urlencoded
html:
- text/html
- application/xhtml+xml
js: text/javascript
json:
- application/json
- text/json
multipartForm: multipart/form-data
rss: application/rss+xml
text: text/plain
hal:
- application/hal+json
- application/hal+xml
xml:
- text/xml
- application/xml
--------------
也可以定义在grails-app/conf/application.groovy中:
grails.mime.types = [ // the first one is the default format
all: '*/*', // 'all' maps to '*' or the first available format in withFormat
atom: 'application/atom+xml',
css: 'text/css',
csv: 'text/csv',
form: 'application/x-www-form-urlencoded',
html: ['text/html','application/xhtml+xml'],
js: 'text/javascript',
json: ['application/json', 'text/json'],
multipartForm: 'multipart/form-data',
rss: 'application/rss+xml',
text: 'text/plain',
hal: ['application/hal+json','application/hal+xml'],
xml: ['text/xml', 'application/xml']
]
#################
请求的响应类型通常有三种:HTML、XML和JSON
为指定响应类型,通常的做法是,通过?format=xml或&format=xml
http://localhost:8080/user/index?format=xml
class UserController {
def index() {
def users = User.list(params)
withFormat {
html userList: users //返回页面
json { render users as JSON } //映射json关键字,返回json格式数据
xml { render users as XML } //映射xml关键字,返回xml格式数据
lvchanglong { render users as JSON} //映射lvchanglong关键字,返回指定格式(json)数据http://localhost:8080/user/index?format=lvchanglong
'*' { render users as JSON } //指定格式与映射关键字未匹配的情况
}
}
}
注意:如果没有指定通配符"*",则会默认选择withFormat中的第一个类型(如例子中的html)进行返回。
##################
URI扩展及举例:
class UserController {
def index() {
def users = User.list(params)
withFormat {
html userList: users //返回页面
json { render users as JSON } //映射json关键字,返回json格式数据
xml { render users as XML } //映射xml关键字,返回xml格式数据
lvchanglong { render users as JSON} //映射lvchanglong关键字,返回指定格式(json)数据http://localhost:8080/user/index?format=lvchanglong
'*' { render users as JSON } //指定格式与映射关键字未匹配的情况
}
}
}
http://localhost:8080/user/index?format=xml
等同于
http://localhost:8080/user/index.xml
更多例子:
http://localhost:8080/user/index.lvchanglong?max=1
http://localhost:8080/user/index.json?max=1
...
##############
极简应用:
class UserController {
def index() {
respond User.list(params)
}
}
http://localhost:8080/user/index.xml
http://localhost:8080/user/index.json
http://localhost:8080/user/index
注意:
此时的http://localhost:8080/user/index?format=xml不等同于http://localhost:8080/user/index.xml
即
http://localhost:8080/user/index?format=xml 无效
http://localhost:8080/user/index.xml 有效
##############
再次强调,使用respond进行响应时,可支持以下三种写法:
http://localhost:8080/user/index
http://localhost:8080/user/index.json
http://localhost:8080/user/index.xml
本文暂时没有评论,来添加一个吧(●'◡'●)