Grails 4 升级后,我的 URL 映射和拦截器不再工作
After Grails 4 upgrade my URL Mappings and interceptors no longer work
我正在尝试从 3.3.x 升级到 4.0.13,但在这样做之后我的 URL 映射和拦截器不再工作。我相信两者之间存在一个相同的根本问题,因为我在拦截器中的调试语句使它看起来底层 grails 映射中的某个人被破坏了。
URL映射
static mappings = {
"/api/admin/$controller/$action?/$id?(.$format)?"{
namespace = "admin"
constraints {
// apply constraints here
}
}
"/"(redirect: "/app/")
"/app"(uri: "/index.html")
"/app/**"(uri: "/index.html")
"500"(view:'/error')
"404"(redirect: "/app/")
}
用户控制器
class UserController extends AdminController {
static namespace = "admin";
def save(UserCommand cmd) {
[...]
}
}
登录拦截器
class LoginInterceptor {
LoginInterceptor() {
matchAll()
.excludes(controller: ~/(login|logout|publicLookupSvc)/);
}
boolean before() {
println(controllerNamespace);
println(controllerName);
println(actionName);
println(request.requestURI);
true
}
}
所以我指的潜在问题是我在 4.0.13 中的调试语句打印 null
而在 3.3.x 中它们实际上打印值
所以如果我访问 URL: http://localhost:8081/raa/api/admin/user/save
在 3.3 中
println(controllerNamespace); -> admin
println(controllerName); -> user
println(actionName); -> save
println(request.requestURI); -> /raa/api/admin/user/save
在 4.0.13
println(controllerNamespace); -> null
println(controllerName); -> null
println(actionName); -> null
println(request.requestURI); -> /raa/api/admin/user/save
连同错误堆栈跟踪
2022-04-20 13:15:33.303 ERROR --- [nio-8081-exec-3] o.g.web.errors.GrailsExceptionResolver : IllegalArgumentException occurred when processing request: [GET] /raa/api/admin/user/save
URL mapping must either provide redirect information, a controller or a view name to map to!. Stacktrace follows:
java.lang.IllegalArgumentException: URL mapping must either provide redirect information, a controller or a view name to map to!
at org.springframework.util.Assert.isTrue(Assert.java:118)
at org.grails.web.mapping.DefaultUrlMappingInfo.<init>(DefaultUrlMappingInfo.java:105)
at org.grails.web.mapping.DefaultUrlMappingInfo.<init>(DefaultUrlMappingInfo.java:99)
at org.grails.web.mapping.ResponseCodeUrlMapping.match(ResponseCodeUrlMapping.java:136)
[...]
因此,由于所有关于我的请求应该被路由到哪里的属性都是空的,所以 matchAll()
也不起作用。当我访问我的 login/logout/publicLookupSvc
控制器时,拦截器仍然被击中,即使它应该被跳过。
我觉得一旦弄清楚为什么没有正确填充这些映射参数,一切就会水到渠成。我就是不明白为什么会这样。
Grails 4.0.13
JDK 11.0.13
Gradle 5.0
您在 Grails 4.x 中声明 contextPath
的方式已经改变,这导致我的所有 URL 都不正确。解决此问题后,一切都按预期工作。
Grails 3.x
server:
contextPath: '/myapp'
Grails 4.x+
server:
servlet:
contextPath: '/myapp'
我正在尝试从 3.3.x 升级到 4.0.13,但在这样做之后我的 URL 映射和拦截器不再工作。我相信两者之间存在一个相同的根本问题,因为我在拦截器中的调试语句使它看起来底层 grails 映射中的某个人被破坏了。
URL映射
static mappings = {
"/api/admin/$controller/$action?/$id?(.$format)?"{
namespace = "admin"
constraints {
// apply constraints here
}
}
"/"(redirect: "/app/")
"/app"(uri: "/index.html")
"/app/**"(uri: "/index.html")
"500"(view:'/error')
"404"(redirect: "/app/")
}
用户控制器
class UserController extends AdminController {
static namespace = "admin";
def save(UserCommand cmd) {
[...]
}
}
登录拦截器
class LoginInterceptor {
LoginInterceptor() {
matchAll()
.excludes(controller: ~/(login|logout|publicLookupSvc)/);
}
boolean before() {
println(controllerNamespace);
println(controllerName);
println(actionName);
println(request.requestURI);
true
}
}
所以我指的潜在问题是我在 4.0.13 中的调试语句打印 null
而在 3.3.x 中它们实际上打印值
所以如果我访问 URL: http://localhost:8081/raa/api/admin/user/save
在 3.3 中
println(controllerNamespace); -> admin
println(controllerName); -> user
println(actionName); -> save
println(request.requestURI); -> /raa/api/admin/user/save
在 4.0.13
println(controllerNamespace); -> null
println(controllerName); -> null
println(actionName); -> null
println(request.requestURI); -> /raa/api/admin/user/save
连同错误堆栈跟踪
2022-04-20 13:15:33.303 ERROR --- [nio-8081-exec-3] o.g.web.errors.GrailsExceptionResolver : IllegalArgumentException occurred when processing request: [GET] /raa/api/admin/user/save
URL mapping must either provide redirect information, a controller or a view name to map to!. Stacktrace follows:
java.lang.IllegalArgumentException: URL mapping must either provide redirect information, a controller or a view name to map to!
at org.springframework.util.Assert.isTrue(Assert.java:118)
at org.grails.web.mapping.DefaultUrlMappingInfo.<init>(DefaultUrlMappingInfo.java:105)
at org.grails.web.mapping.DefaultUrlMappingInfo.<init>(DefaultUrlMappingInfo.java:99)
at org.grails.web.mapping.ResponseCodeUrlMapping.match(ResponseCodeUrlMapping.java:136)
[...]
因此,由于所有关于我的请求应该被路由到哪里的属性都是空的,所以 matchAll()
也不起作用。当我访问我的 login/logout/publicLookupSvc
控制器时,拦截器仍然被击中,即使它应该被跳过。
我觉得一旦弄清楚为什么没有正确填充这些映射参数,一切就会水到渠成。我就是不明白为什么会这样。
Grails 4.0.13
JDK 11.0.13
Gradle 5.0
您在 Grails 4.x 中声明 contextPath
的方式已经改变,这导致我的所有 URL 都不正确。解决此问题后,一切都按预期工作。
Grails 3.x
server:
contextPath: '/myapp'
Grails 4.x+
server:
servlet:
contextPath: '/myapp'