@ -37,47 +37,37 @@ import org.springframework.web.bind.annotation.RequestMethod;
@@ -37,47 +37,37 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping ;
/ * *
* Implementation of the { @link org . springframework . web . servlet . HandlerMapping }
* interface that maps handlers based on HTTP paths expressed through the
* { @link RequestMapping } annotation at the type or method level .
* Implementation of the { @link org . springframework . web . servlet . HandlerMapping } interface that maps handlers based on
* HTTP paths expressed through the { @link RequestMapping } annotation at the type or method level .
*
* < p > Registered by default in { @link org . springframework . web . servlet . DispatcherServlet }
* on Java 5 + . < b > NOTE : < / b > If you define custom HandlerMapping beans in your
* DispatcherServlet context , you need to add a DefaultAnnotationHandlerMapping bean
* explicitly , since custom HandlerMapping beans replace the default mapping strategies .
* Defining a DefaultAnnotationHandlerMapping also allows for registering custom
* interceptors :
* < p > Registered by default in { @link org . springframework . web . servlet . DispatcherServlet } on Java 5 + . < b > NOTE : < / b > If you
* define custom HandlerMapping beans in your DispatcherServlet context , you need to add a
* DefaultAnnotationHandlerMapping bean explicitly , since custom HandlerMapping beans replace the default mapping
* strategies . Defining a DefaultAnnotationHandlerMapping also allows for registering custom interceptors :
*
* < pre class = "code" >
* & lt ; bean class = "org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" & gt ;
* & lt ; property name = "interceptors" & gt ;
* . . .
* & lt ; / property & gt ;
* & lt ; / bean & gt ; < / pre >
* < pre class = "code" > & lt ; bean class = "org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" & gt ;
* & lt ; property name = "interceptors" & gt ; . . . & lt ; / property & gt ; & lt ; / bean & gt ; < / pre >
*
* Annotated controllers are usually marked with the { @link Controller } stereotype
* at the type level . This is not strictly necessary when { @link RequestMapping } is
* applied at the type level ( since such a handler usually implements the
* { @link org . springframework . web . servlet . mvc . Controller } interface ) . However ,
* { @link Controller } is required for detecting { @link RequestMapping } annotations
* at the method level if { @link RequestMapping } is not present at the type level .
* Annotated controllers are usually marked with the { @link Controller } stereotype at the type level . This is not
* strictly necessary when { @link RequestMapping } is applied at the type level ( since such a handler usually implements
* the { @link org . springframework . web . servlet . mvc . Controller } interface ) . However , { @link Controller } is required for
* detecting { @link RequestMapping } annotations at the method level if { @link RequestMapping } is not present at the type
* level .
*
* < p > < b > NOTE : < / b > Method - level mappings are only allowed to narrow the mapping
* expressed at the class level ( if any ) . HTTP paths need to uniquely map onto
* specific handler beans , with any given HTTP path only allowed to be mapped
* onto one specific handler bean ( not spread across multiple handler beans ) .
* It is strongly recommended to co - locate related handler methods into the same bean .
* < p > < b > NOTE : < / b > Method - level mappings are only allowed to narrow the mapping expressed at the class level ( if any ) .
* HTTP paths need to uniquely map onto specific handler beans , with any given HTTP path only allowed to be mapped onto
* one specific handler bean ( not spread across multiple handler beans ) . It is strongly recommended to co - locate related
* handler methods into the same bean .
*
* < p > The { @link AnnotationMethodHandlerAdapter } is responsible for processing
* annotated handler methods , as mapped by this HandlerMapping . For
* { @link RequestMapping } at the type level , specific HandlerAdapters such as
* { @link org . springframework . web . servlet . mvc . SimpleControllerHandlerAdapter } apply .
* < p > The { @link AnnotationMethodHandlerAdapter } is responsible for processing annotated handler methods , as mapped by
* this HandlerMapping . For { @link RequestMapping } at the type level , specific HandlerAdapters such as { @link
* org . springframework . web . servlet . mvc . SimpleControllerHandlerAdapter } apply .
*
* @author Juergen Hoeller
* @author Arjen Poutsma
* @since 2 . 5
* @see RequestMapping
* @see AnnotationMethodHandlerAdapter
* @since 2 . 5
* /
public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandlerMapping {
@ -85,23 +75,19 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
@@ -85,23 +75,19 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
private final Map < Class , RequestMapping > cachedMappings = new HashMap < Class , RequestMapping > ( ) ;
/ * *
* Set whether to register paths using the default suffix pattern as well :
* i . e . whether "/users" should be registered as "/users.*" and "/users/" too .
* < p > Default is "true" . Turn this convention off if you intend to interpret
* your < code > @RequestMapping < / code > paths strictly .
* < p > Note that paths which include a ".xxx" suffix or end with "/" already will not be
* transformed using the default suffix pattern in any case .
* Set whether to register paths using the default suffix pattern as well : i . e . whether "/users" should be registered
* as "/users.*" and "/users/" too . < p > Default is "true" . Turn this convention off if you intend to interpret your
* < code > @RequestMapping < / code > paths strictly . < p > Note that paths which include a ".xxx" suffix or end with "/"
* already will not be transformed using the default suffix pattern in any case .
* /
public void setUseDefaultSuffixPattern ( boolean useDefaultSuffixPattern ) {
this . useDefaultSuffixPattern = useDefaultSuffixPattern ;
}
/ * *
* Checks for presence of the { @link org . springframework . web . bind . annotation . RequestMapping }
* annotation on the handler class and on any of its methods .
* Checks for presence of the { @link org . springframework . web . bind . annotation . RequestMapping } annotation on the handler
* class and on any of its methods .
* /
@Override
protected String [ ] determineUrlsForHandler ( String beanName ) {
@ -120,11 +106,19 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
@@ -120,11 +106,19 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
if ( ! typeLevelPattern . startsWith ( "/" ) ) {
typeLevelPattern = "/" + typeLevelPattern ;
}
boolean hasEmptyMethodLevelMappings = false ;
for ( String methodLevelPattern : methodLevelPatterns ) {
String combinedPattern = getPathMatcher ( ) . combine ( typeLevelPattern , methodLevelPattern ) ;
addUrlsForPath ( urls , combinedPattern ) ;
if ( methodLevelPattern = = null ) {
hasEmptyMethodLevelMappings = true ;
} else {
String combinedPattern = getPathMatcher ( ) . combine ( typeLevelPattern , methodLevelPattern ) ;
addUrlsForPath ( urls , combinedPattern ) ;
}
}
if ( hasEmptyMethodLevelMappings | |
org . springframework . web . servlet . mvc . Controller . class . isAssignableFrom ( handlerType ) ) {
addUrlsForPath ( urls , typeLevelPattern ) ;
}
addUrlsForPath ( urls , typeLevelPattern ) ;
}
return StringUtils . toStringArray ( urls ) ;
}
@ -144,6 +138,9 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
@@ -144,6 +138,9 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
/ * *
* Derive URL mappings from the handler ' s method - level mappings .
*
* < p > The returned array may contain { @code null } , indicating an empty { @link RequestMapping } value .
*
* @param handlerType the handler type to introspect
* @return the array of mapped URLs
* /
@ -156,19 +153,25 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
@@ -156,19 +153,25 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
public void doWith ( Method method ) {
RequestMapping mapping = AnnotationUtils . findAnnotation ( method , RequestMapping . class ) ;
if ( mapping ! = null ) {
String [ ] mappedPaths = mapping . value ( ) ;
for ( String mappedPath : mappedPaths ) {
addUrlsForPath ( urls , mappedPath ) ;
String [ ] mappedPatterns = mapping . value ( ) ;
if ( mappedPatterns . length > 0 ) {
for ( String mappedPattern : mappedPatterns ) {
addUrlsForPath ( urls , mappedPattern ) ;
}
} else {
// empty method-level RequestMapping
urls . add ( null ) ;
}
}
}
} ) ;
} , ReflectionUtils . NON_BRIDGED_METHODS ) ;
}
return StringUtils . toStringArray ( urls ) ;
}
/ * *
* Add URLs and / or URL patterns for the given path .
*
* @param urls the Set of URLs for the current bean
* @param path the currently introspected path
* /
@ -180,9 +183,9 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
@@ -180,9 +183,9 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
}
}
/ * *
* Validate the given annotated handler against the current request .
*
* @see # validateMapping
* /
@Override
@ -197,8 +200,9 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
@@ -197,8 +200,9 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
}
/ * *
* Validate the given type - level mapping metadata against the current request ,
* checking HTTP request method and parameter conditions .
* Validate the given type - level mapping metadata against the current request , checking HTTP request method and
* parameter conditions .
*
* @param mapping the mapping metadata to validate
* @param request current HTTP request
* @throws Exception if validation failed
@ -220,9 +224,9 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
@@ -220,9 +224,9 @@ public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandler
String [ ] mappedHeaders = mapping . headers ( ) ;
if ( ! ServletAnnotationMappingUtils . checkHeaders ( mappedHeaders , request ) ) {
throw new ServletRequestBindingException ( "Header conditions \"" +
StringUtils . arrayToDelimitedString ( mappedHeaders , ", " ) +
"\" not met for actual request" ) ;
throw new ServletRequestBindingException (
"Header conditions \"" + StringUtils . arrayToDelimitedString ( mappedHeaders , ", " ) +
"\" not met for actual request" ) ;
}
}