3

我想基本上在 UrlMappings.groovy 中进行 URL 重写,例如:

"/pub/cdn/$version/**"(uri: request.forwardURI.replaceFirst("/pub/cdn/[0-9]*", ""))

因此请求:

/pub/cdn/1327516405188/css/login.css

例如,将被翻译为:

/css/login.css

这个想法是获取原始 URI 并去除一些路径,然后传递新的 URI。

但是,使用上面的代码,我得到了错误:

>    org.springframework.beans.factory.BeanCreationException: Error
>    creating bean with name 'grailsUrlMappingsHolder': Cannot resolve
>    reference to bean 'urlMappingsTargetSource' while setting bean
>    property 'targetSource'; nested exception is
>    ...
>    groovy.lang.MissingPropertyException: No such property: forwardURI for
>    class: java.lang.String

这似乎暗示请求对象是一个字符串。有没有办法在 UrlMappings.groovy 中获取原始 URI?

只要新路径是硬编码的,“/old/path”(uri:“/new/path”)方法就可以工作,但我无法弄清楚如何将原始请求的路径作为 UrlMappings 中的变量访问班级。

PS 我尝试让 UrlMappings 调用控制器:

"/pub/cdn/$version/**" {
    controller = "image"
    action = "cdnRedirect"
}

在控制器中:

def cdnRedirect = {
    def newUri = request.forwardURI?.toString().replaceFirst("/pub/cdn/[0-9]*", "")
    return redirect(uri: newUri)
}

虽然控制器闭包被正确调用,并且 URI 被正确翻译,但重定向似乎根本没有做任何事情。

4

1 回答 1

2

根据您的示例,在我看来,您正在解决错误的问题。这里真正的问题似乎是您正在使用相对链接(例如css/login.css)到静态内容。当浏览器选择一个相对链接时,它使用当前 url 来确定文件的路径。

但是,如果您使用 Grails 的resourcetag,grails 将生成一个锚定到 URL 根的 URL。例如,您的css/login.css链接将变为/myAppName/css/login.css.

用法是这样的:

<link type="text/css" href="${resource(dir: 'css', file: 'login.css')}" />

这保证了无论控制器、操作或其他 ID 信息如何,指向 CSS 文件的链接都将始终正确。


至于为什么你的 UrlMapping 不起作用,那是因为它没有被动态处理。它是在应用程序启动期间处理的,因此当时request甚至不存在该对象。

如果你绝对需要一个 URL 重写系统,并且使用控制器来处理资源对于这个目的来说太复杂了,我建议将你的 servlet 引擎(即 Tomcat)放在 Apache 之后,并且只使用mod_rewrite. 然而,如果设计得当,这确实不是必需的。


编辑

只是为了完整的信息,要获得映射的动态控制是使用动态控制器和动作名称中指定的语法。但是,这有点受限,您仍然不能使用它来执行重定向。

于 2012-01-26T04:38:21.267 回答