NCNecros
NCNecros

Reputation: 2415

spring two method with same URL mapping

I have 2 class with 2 same URL mappings:

@RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodA(@PathVariable(TOPIC_ID) Long topicId) {
    ...
}
//
@RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodB(@PathVariable(TOPIC_ID) Long topicId) {
    ...
}

MethodB is in a class that is loaded dynamically. I want use methodA only if methodB is not available. If methodB is available the Spring uses only it. How can I do that.

Upvotes: 0

Views: 1617

Answers (3)

Serge Ballesta
Serge Ballesta

Reputation: 148965

The spring way would be to have only one controller mapped to an URL, and to inject the dynamic class that actually does the job in it:

class A {
    @Autowired(required = false)
    class B b; // inject by Spring or by ... or not at all
    ...
    @RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
    public ModelAndView methodA(@PathVariable(TOPIC_ID) Long topicId) {
        if (b != NULL) {  // class B has been found and injected
            return b.methodB(topicId)
        }
        // fallback ...
        ...
    } 
}

class B {
    // NO @RequestMapping here !
    public ModelAndView methodB(@PathVariable(TOPIC_ID) Long topicId) {
        ...
    }
}

Upvotes: 1

Mavlarn
Mavlarn

Reputation: 3883

In spring, a controller object is a singleton bean in spring context, and the context is initialized during starting. So, if a class is dynamically loaded, the request mapping will not be applied. So you can not do what you said.

The solution above of ZeroOne is the only way I think.

Upvotes: 0

ZeroOne
ZeroOne

Reputation: 3171

It sounds really confusing to sometimes have the URL mapping come from one package and sometimes from another. Why don't you do as Ken Bekov suggested in a comment and have just one class where there's the URL mapping and have that class dynamically decide which implementation to use? So something like this:

@RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodA(@PathVariable(TOPIC_ID) Long topicId) {
 Class classWithMapping;
 try {
   classWithMapping = Class.forName("class.that.MayNotExist");
 } catch(ClassNotFoundException cnfe) {
   classWithMapping = MyDefaultClass.class;
 }
 // ....
}

...and then instantiate classWithMapping using reflection or Spring's application context.

Upvotes: 1

Related Questions