Search code examples
grails

After Grails 4 upgrade my URL Mappings and interceptors no longer work


I am trying to upgrade from 3.3.x to 4.0.13 but after doing so my URL mappings and interceptors no longer work. I believe there is a root issue that is the same between the 2 because of debug statements I have in my interceptor make it appear someone in the underlying grails mappings is broken.

URLMappings

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/")
    }

UserController

class UserController extends AdminController {
    static namespace = "admin";

    def save(UserCommand cmd) {
       [...]
    }
}

LoginInterceptor

class LoginInterceptor {

    LoginInterceptor() {
        matchAll()
                .excludes(controller: ~/(login|logout|publicLookupSvc)/);
    }

    boolean before() {
        println(controllerNamespace);
        println(controllerName);
        println(actionName);
        println(request.requestURI);

        true
    }
}

So the underlying issue I am referring to is that my debug statments in 4.0.13 print null whereas in 3.3.x they actually print values

So if I visit the URL: http://localhost:8081/raa/api/admin/user/save

In 3.3

println(controllerNamespace); -> admin
println(controllerName); -> user
println(actionName); -> save
println(request.requestURI); -> /raa/api/admin/user/save

In 4.0.13

println(controllerNamespace); -> null
println(controllerName); -> null
println(actionName); -> null
println(request.requestURI); -> /raa/api/admin/user/save

Along with the error stacktrace

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)
    [...]

Consequently, since all the attributes are null regarding where my request is suposed to be routed, the matchAll() does not work either. When I vist my login/logout/publicLookupSvc controllers the interceptor still gets hit even though it should be skipped.

I feel like once I figure out why those mapping paramters are not being populated correctly everything will fall into place. I just can't figure out why thats happening.

Grails 4.0.13

JDK 11.0.13

Gradle 5.0


Solution

  • The way you delcared your contextPath in Grails 4.x has changed and this was causing all my URL to be incorrect. After fixing this everything worked as expected.

    Grails 3.x

    server:
      contextPath: '/myapp'
    

    Grails 4.x+

    server:
      servlet:
         contextPath: '/myapp'