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'