Shaw
Shaw

Reputation: 1494

Spring MVC and annotated controllers issue:

I'm having a strange issue with annotated controllers and Spring MVC. I was trying to use Annotated controllers for the sample MVC application that Spring ships with its documentation. I used 2.5 version.

When I specify @RequestMapping at type level, I get "HTTP ERROR: 500 No adapter for handler [Controller class name]: Does your handler implement a supported interface like Controller?

If I include it in the method level, it works fine with out an issue. Adding or removing the default handle adapters to context files made no difference:

Finally, I resorted to having @RequestMapping at controller level, as well as one at the Method level, and it worked. Anyone know what could be the issue?

Here is the sample code:

This did not work:

@Controller
@RequestMapping("/*")
public class InventoryController {
    protected final Log logger = LogFactory.getLog(getClass());

    @Autowired
    private ProductManager productManager;


    public ModelAndView inventoryHandler() {
        String now = (new java.util.Date()).toString();
        logger.info("returning hello view with " + now);
        Map<String, Object> myModel = new HashMap<String, Object>();
        myModel.put("now", now);
        myModel.put("products", this.productManager.getProducts());
        return new ModelAndView("hello", "model", myModel);
    }
}

This worked:

@Controller

public class InventoryController {
    protected final Log logger = LogFactory.getLog(getClass());

    @Autowired
    private ProductManager productManager;

    @RequestMapping("/hello.htm")
    public ModelAndView inventoryHandler() {
        String now = (new java.util.Date()).toString();
        logger.info("returning hello view with " + now);
        Map<String, Object> myModel = new HashMap<String, Object>();
        myModel.put("now", now);
        myModel.put("products", this.productManager.getProducts());
        return new ModelAndView("hello", "model", myModel);
    }
}

This also worked:

@Controller
@RequestMapping("/*")
public class InventoryController {
    protected final Log logger = LogFactory.getLog(getClass());

    @Autowired
    private ProductManager productManager;

    @RequestMapping( method = RequestMethod.GET, value = "/hello.htm" )
    public ModelAndView inventoryHandler() {
        String now = (new java.util.Date()).toString();
        logger.info("returning hello view with " + now);
        Map<String, Object> myModel = new HashMap<String, Object>();
        myModel.put("now", now);
        myModel.put("products", this.productManager.getProducts());
        return new ModelAndView("hello", "model", myModel);
    }
}

Any ideas, what's happening here? I did a lot of search and no solution. I also tried with 2.5.6, and the issue was similar.

Upvotes: 1

Views: 7590

Answers (3)

Gene De Lisa
Gene De Lisa

Reputation: 3838

You don't need to use @RequestMapping on the class. It is just a convenience. You do need the method level @RequestMapping annotations.

Given this:

@Controller
public class InventoryController {
...
@RequestMapping("/inventory/create/{id}")
public void create(...){}

@RequestMapping("/inventory/delete/{id}")
public void delete(...){}
...

You can factor out the inventory part of the URI.

@Controller
@RequestMapping("/inventory")
public class InventoryController {
...
@RequestMapping("create/{id}")
public void create(...){}

@RequestMapping("delete/{id}")
public void delete(...){}
...

Upvotes: 3

rodrigoap
rodrigoap

Reputation: 7480

This is beacuse the first configuration doesn't tell wich method of the class invoke.

Upvotes: 1

skaffman
skaffman

Reputation: 403441

You need to put @RequestMapping on the method because putting it on the class isn't enough information - Spring needs to know which method to call to handle the request.

If your class only has one method, then understandably you might think that it would pick that, but it doesn't.

Consider that one of the benefits of annotated controllers is that you can have as many @RequestMapping-annotated methods in your class as you want.

Upvotes: 7

Related Questions