History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: SPR-4129
Type: Improvement Improvement
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Juergen Hoeller
Reporter: Matt Raible
Votes: 4
Watchers: 5
Operations

If you were logged in you would be able to see more operations.
Spring Framework

Allow ControllerClassNameHandlerMapping and @Controller to work together

Created: 19/Nov/07 05:18 PM   Updated: Sunday 09:50 PM
Component/s: SpringWEB
Affects Version/s: 2.5 RC2
Fix Version/s: 2.5.3

Time Tracking:
Not Specified

Issue Links:
Related
 

Virtual Machine: Mac OS X JVM - 1.5
Platform: Resin - 3.0


 Description  « Hide
It would be nice if ControllerClassNameHandlerMapping and @Controller could work together. So the URLs could be determined by ControllerClassNameHandlerMapping and you could simply add @Controller and @Autowired to your controllers.

The following URL contains more information on this (missing) feature:

http://forum.springframework.org/showthread.php?p=151750


 All   Comments   Work Log   Change History   FishEye   Related Builds      Sort Order: Ascending order - Click to sort in descending order
Juergen Hoeller - 26/Mar/08 10:55 AM
As of Spring 2.5.3, ControllerClassNameHandlerMapping detects @Controller beans by default as well, treating them analogous to MultiActionControllers. Thanks for the suggestion!

This will be available in the next 2.5.3 snapshot (http://static.springframework.org/downloads/nightly/snapshot-download.php?project=SPR). Feel free to give it a try...

Juergen

Matt Raible - 10/Apr/08 01:13 PM
This doesn't seem to work like I expect it to. Here's what I'd expect:

1. Add @Controller scanning to *-servlet.xml:

<context:component-scan base-package="org.appfuse.web.controller"/>

2. Create a class with @Controller annotation:

package org.appfuse.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


@Controller
public class HomeController {

    @RequestMapping(method = RequestMethod.GET)
    public String index() {
        System.out.println("in index...");
        return "home";
    }
}

3. This Controller is available at /home.html.

The only way I can get #3 to work is if I add @RequestMapping("/home") to the class. I thought this wouldn't be required anymore? I tried adding the following to my servlet.xml, but it didn't help either:

<bean id="urlMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

Thanks,

Matt

Tom Duffey - 14/Apr/08 11:58 AM
Any response to Matt's comments? I upgraded from 2.5.2 and had to revert back because it didn't work as expected and like Matt I thought the ControllerClassNameHandlerMapping would determine the request mapping path.

Keith Donald - 14/Apr/08 12:27 PM
In Matt's example the index method on HomeController would be mapped to the URL /home/index by the 2.5.3 convention, which I imagine isn't what he wants.

Just to provide more usage examples of this feature, here is an example in the Spring MVC + Web Flow reference application "booking-mvc". You can see the code on-line here: https://springframework.svn.sourceforge.net/svnroot/springframework/spring-webflow/trunk/spring-webflow-samples/booking-mvc

Specifically see:

@Controller code: https://springframework.svn.sourceforge.net/svnroot/springframework/spring-webflow/trunk/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/HotelsController.java

Config:
https://springframework.svn.sourceforge.net/svnroot/springframework/spring-webflow/trunk/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/config/webmvc-config.xml

The URls mapped by convention are then:

/hotels/index
/hotels/search
/hotels/show
/hotels/deleteBooking

But no, /hotels doesn't mapped to to the index method by default... not in 2.5.3 anyway. Is this the convention you want? Perhaps we could employ a convention to map the root controller URL e.g. /home to a "home" method on the HomeController...

Matt Raible - 15/Apr/08 04:17 PM
Thanks Keith - your webmvc-config.xml seems to contain the magic sauce that makes this work as expected.

Adding the following allows /home/index.html to work:

    <!-- Enables convention-based request URL mapping to @Controllers e.g. /home/* maps to HomeController -->
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<property name="order" value="1"/>
</bean>

Additionally adding the URL mapping bean below allows /home.html to work:

<!-- Maps all other request URLs to views -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="defaultHandler">
<!-- Selects view names to render based on the request URI: e.g. /index selects "index" -->
<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
</property>
<property name="order" value="2"/>
</bean>

Is it possible to make these the defaults or would that mess up too much backwards compatibility? The next thing I'm going to ask for is to eliminate @Controller and detect class names that end with Controller. ;-)

Thanks,

Matt

Matt Raible - 15/Apr/08 04:20 PM
BTW, is there anything being done to allow extensionless URLs? I'd love to have /home/index or home instead of /spring/home or /home.html. I realize I can use UrlRewriteFilter, but it seems like I'd have to add entries for each Controller's URL to my urlrewrite.xml.

Tom Duffey - 20/Jul/08 09:50 PM
For what it's worth, I finally just got back to this issue and solved it by extending ControllerClassNameHandlerMapping with my own isMultiActionControllerType() method. Mine has an extra check to see if the controller has the @Controller annotation but does NOT have any @RequestMapping annotations.

This is how must of the controllers in our application are setup (@Controller + ControllerClassNameHandlerMapping without @RequestMapping) and it seems to work OK.