garyj garyj - 17 days ago 12
Java Question

Spring MVC @RequestMapping Inheritance

Coming from Struts2 I'm used to declaring

@Namespace
annotation on super classes (or
package-info.java
) and inheriting classes would subsequently pick up on the value in the
@Namespace
annotation of its ancestors and prepend it to the request path for the Action. I am now trying to do something similar in Spring MVC using
@RequestMapping
annotation as follows (code trimmed for brevity):

package au.test

@RequestMapping(value = "/")
public abstract class AbstractController {
...
}

au.test.user

@RequestMapping(value = "/user")
public abstract class AbstractUserController extends AbstractController {

@RequestMapping(value = "/dashboard")
public String dashboard() {
....
}
}

au.test.user.twitter

@RequestMapping(value = "/twitter")
public abstract class AbstractTwitterController extends AbstractUserController {
...
}

public abstract class TwitterController extends AbstractTwitterController {

@RequestMapping(value = "/updateStatus")
public String updateStatus() {
....
}
}



  • /
    works as expect

  • /user/dashboard
    works as expected

  • However when I would have expected
    /user/twitter/updateStatus
    to work it does not and checking the logs I can see a log entry which looks something like:




org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
- Mapped URL path [/tweeter/updateStatus] onto handler
'twitterController'


Is there a setting I can enable that will scan the superclasses for
@RequestMapping
annotations and construct the correct path?

Also I take it that defining
@RequestMapping
on a package in
package-info.java
is illegal?

Answer

The following basically becomes /tweeter/updateStatus and not /user/tweeter/updateStatus

public abstract class TwitterController extends AbstractTwitterController {

    @RequestMapping(value = "/updateStatus")    
    public String updateStatus() {
        ....
    }
}

That's the expected behavior since you've overriden the original @RequestMapping you've declared in the AbstractController and AbstractUserController.

In fact when you declared that AbstractUserController it also overriden the @RequestMapping for AbstractController. It just gives you the illusion that the / from the AbstractController has been inherited.

"Is there a setting I can enable that will scan the superclasses for @RequestMapping annotations and construct the correct path?" Not that I know of.