是否有过想在Filter中调用标签库的冲动?Luke Daley在其博文中,给出了解决之道。
文中,Luke Daley以Filter为例,演示了在其中调用createlink的方法:
import org.codehaus.groovy.grails.web.pages.GroovyPage
import org.springframework.web.context.request.RequestContextHolder
class HttpsOnlyFilter {
def gspTagLibraryLookup
def filters = {
...
def link = invokeTag("createLink", [
controller: controllerName,
action: actionName,
params: params,
base: "https://secure.domain.com"
]).toString()
......
}
def invokeTag(name, attrs = [:], body = null) {
def namespace
def tagName
if (name.contains(":")) {
def split = name.split(":", 2)
namespace = split[0]
tagName = split[1]
} else {
namespace = GroovyPage.DEFAULT_NAMESPACE
tagName = name
}
GroovyPage.captureTagOutput( gspTagLibraryLookup
, namespace
, tagName
, attrs
, body
, RequestContextHolder.currentRequestAttributes())
}
}
invokeTag方法的参数为标签名、属性Map以及可选的闭包参数,如果标签名没有包含namespace,就会使用g。指定namespace的用法如下:
invokeTag("someNamespace:someTag", [param1: 1])
值得注意的是,Luke Daley也表示,如果你想在View之外调用标签库,这很可能是一个设计问题。同时,上述方法只适合在Request环境中使用,否则RequestContextHolder.currentRequestAttributes()将返回null。一种绕过这种限制的方法是用GrailsWebUtil.bindMockWebRequest()造出一个模拟环境。
除了Luke Daley介绍的方法外,还可以使用如下方式获得Createlink的内容:
def g = new org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib() //获得绝对link为:http://localhost:8080/jqac/role/index def absoluteLink = g.createLink(controller: 'role', action: 'index',absolute:"true") //获得相对link为:/jqac/role/index def relativeLink = g.createLink(controller: 'role', action: 'index')
而这个方法的缺点是只能使用缺省的namespace,即g。如果要用自己定义的taglib,则可用如下方法:
def groovyq=new temp.GroovyqTagLib()
groovyq.mylink()
//GroovyqTagLib代码如下:
package temp
class GroovyqTagLib {
static namespace = "groovyq"
def mylink = {
out << "http://localhost:8080/temp/person"
}
}
关于Luke Daley提供的完整代码请参见原文。

最新评论
9 周 6 小时之前
9 周 1 天之前
11 周 5 天之前
11 周 5 天之前
17 周 2 天之前
17 周 4 天之前
19 周 3 天之前
20 周 1 天之前
20 周 2 天之前
20 周 5 天之前