Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ControllerClassNameHandlerMapping and @Controller to work together [SPR-4129] #8808

Closed
spring-projects-issues opened this issue Nov 19, 2007 · 7 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Nov 19, 2007

Matt Raible opened SPR-4129 and commented

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


Affects: 2.5 RC2

Issue Links:

4 votes, 5 watchers

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

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

@spring-projects-issues
Copy link
Collaborator Author

Matt Raible commented

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"/>

  1. 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";
}

}

  1. 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

@spring-projects-issues
Copy link
Collaborator Author

Tom Duffey commented

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.

@spring-projects-issues
Copy link
Collaborator Author

Keith Donald commented

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...

@spring-projects-issues
Copy link
Collaborator Author

Matt Raible commented

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

@spring-projects-issues
Copy link
Collaborator Author

Matt Raible commented

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.

@spring-projects-issues
Copy link
Collaborator Author

Tom Duffey commented

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants