views:

383

answers:

2

Hey there,

actually I thought I was trying something really simple. ControllerClassNameHandlerMapping sounded great to produce a small spring webapp using a very lean configuration. Just annotate the Controller with @Controller, have it extend AbstractController and the configuration shouldn't need more than this

<context:component-scan base-package="test.mypackage.controller" />
<bean id="urlMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />

to resolve my requests and map them to my controllers. I've mapped the servlet to "*.spring", and calling

<approot>/hello.spring

All I ever get is an error stating that no mapping was found. If however I extend the MultiActionController, and do something like

<approot>/hello/hello.spring

it works. Which somehow irritates me, as I would have thought that if that is working, why didn't my first try? Does anyone have any idea? The two controllers I used looked like this

@Controller
public class HelloController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView modelAndView = new ModelAndView("hello");
    modelAndView.addObject("message", "Hello World!");
    return modelAndView;
    }
}

and

@Controller
public class HelloController extends MultiActionController {
public ModelAndView hello(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView modelAndView = new ModelAndView("hello");
    modelAndView.addObject("message", "Hello World!");
    return modelAndView;
    }
}
+1  A: 

You shouldn't be using @Controller at the same time as extending from AbstractController. Do one or the other.

Also, @Controller should be used along with the @RequestMapping annotation.

If you want lean config, then just put this in your config file:

<context:component-scan base-package="test.mypackage.controller" />

And use this class:

@Controller
public class HelloController {

   @RequestMapping("/hello")
   public String handle(ModelMap model) {
      model.addAttribute("message", "Hello World!");
      return "hello";
   }
}

In fact, you can probably leave out the return value altogether, Spring should infer the view name "hello" from the request path, but I left this in for clarity.

skaffman
Well, I guess what I was trying to do simply isn't possible with Spring. My idea was to simply declare the ControllerClassNameHandlerMapping and Spring would infer everything else from the request url using naming conventions to figure out which controllers to invoke. To be honest thats what I understood when I read "convention over configuration". However I quickly found out that Spring doesn't consider classes that aren't either declared as beans or annotated as @Controllers. But if I'm stuck with configuring which classes are controllers anyway, the annotation approach seems to be cleaner.
whiskerz
@whiskerz: I'm confused - the solution I gave you has *less* configuration and code than the one you proposed.
skaffman
Aye, thats why I think its cleaner :-). However consider that Spring would not need to be told about controllers (via <bean> or @Controller), but instead would automagically search for anything extending the Controller interface. Thats what I had expected when I first started out with using ControllerClassNameHandlerMapping. Then all you would need to do was declare <bean id="urlMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" /> and you wouldn't need annotations nor anything else to map <someurl>/home to the HomeController. Pure Convention ^.^
whiskerz
A: 

As of Spring 3.0, the AbstractController class and its kins (SimpleFormController, AbstractFormController etc etc) are deprecated. So just don't use them anymore. The annotation based @MVC model is far more powerful and flexible.

Hans Westerbeek
I'll be stuck with spring 2.5.6 for some time still, however I am looking forward to using spring 3 :-).
whiskerz
That doesn't matter. Just use the annotation format. Forget about AbstractController etc.
Hans Westerbeek