@ -20,13 +20,13 @@ import java.lang.reflect.Method;
@@ -20,13 +20,13 @@ import java.lang.reflect.Method;
import org.springframework.core.annotation.AnnotationUtils ;
import org.springframework.stereotype.Controller ;
import org.springframework.util.PathMatcher ;
import org.springframework.web.bind.annotation.RequestMapping ;
import org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition ;
import org.springframework.web.servlet.mvc.condition.HeadersRequestCondition ;
import org.springframework.web.servlet.mvc.condition.ParamsRequestCondition ;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition ;
import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition ;
import org.springframework.web.servlet.mvc.condition.RequestCondition ;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition ;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo ;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping ;
@ -41,9 +41,28 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
@@ -41,9 +41,28 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
* /
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping {
private boolean useSuffixPatternMatch = true ;
/ * *
* Set whether to use a suffix pattern match ( ".*" ) when matching patterns to URLs .
* If enabled a method mapped to "/users" will also match to "/users.*" .
* < p > Default is "true" . Turn this convention off if you intend to interpret path mappings strictly .
* /
public void setUseSuffixPatternMatch ( boolean useSuffixPatternMatch ) {
this . useSuffixPatternMatch = useSuffixPatternMatch ;
}
/ * *
* Returns the value of the useSuffixPatternMatch flag , see { @link # setUseSuffixPatternMatch ( boolean ) } .
* /
public boolean isUseSuffixPatternMatch ( ) {
return useSuffixPatternMatch ;
}
/ * *
* { @inheritDoc } The handler determination in this method is made based on the presence of a type - level { @link
* Controller } annotation .
* { @inheritDoc }
* The default implementation checks for the presence of a type - level { @link Controller }
* annotation via { @link AnnotationUtils # findAnnotation ( Class , Class ) } .
* /
@Override
protected boolean isHandler ( Class < ? > beanType ) {
@ -51,40 +70,54 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
@@ -51,40 +70,54 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi
}
/ * *
* Provides a { @link RequestMappingInfo } for the given method . < p > Only { @link RequestMapping @RequestMapping } - annotated
* methods are considered . Type - level { @link RequestMapping @RequestMapping } annotations are also detected and their
* attributes combined with method - level { @link RequestMapping @RequestMapping } attributes .
* Determines if the given method is a handler method and creates a { @link RequestMappingInfo } for it .
*
* < p > The default implementation expects the presence of a method - level @ { @link RequestMapping }
* annotation via { @link AnnotationUtils # findAnnotation ( Class , Class ) } . The presence of
* type - level annotations is also checked and if present a RequestMappingInfo is created for each type -
* and method - level annotations and combined via { @link RequestMappingInfo # combine ( RequestMappingInfo ) } .
*
* @param method the method to create a mapping for
* @param method the method to create a RequestMappingInfo for
* @param handlerType the actual handler type , possibly a sub - type of { @code method . getDeclaringClass ( ) }
* @return the mapping , or { @code null }
* @see RequestMappingInfo # combine ( RequestMappingInfo , PathMatcher )
* @return the info , or { @code null }
* /
@Override
protected RequestMappingInfo getMappingForMethod ( Method method , Class < ? > handlerType ) {
RequestMapping methodAnnotation = AnnotationUtils . findAnnotation ( method , RequestMapping . class ) ;
if ( methodAnnotation = = null ) {
return null ;
}
RequestMappingInfo methodInfo = createFromRequestMapping ( methodAnnotation ) ;
RequestMapping typeAnnotation = AnnotationUtils . findAnnotation ( handlerType , RequestMapping . class ) ;
if ( typeAnnotation ! = null ) {
RequestMappingInfo typeInfo = createFromRequestMapping ( typeAnnotation ) ;
return typeInfo . combine ( methodInfo ) ;
}
else {
return methodInfo ;
RequestMapping methodAnnot = AnnotationUtils . findAnnotation ( method , RequestMapping . class ) ;
if ( methodAnnot ! = null ) {
RequestMapping typeAnnot = AnnotationUtils . findAnnotation ( handlerType , RequestMapping . class ) ;
RequestMappingInfo methodInfo = createRequestMappingInfo ( methodAnnot , handlerType , method ) ;
if ( typeAnnot ! = null ) {
RequestMappingInfo typeInfo = createRequestMappingInfo ( typeAnnot , handlerType , method ) ;
return typeInfo . combine ( methodInfo ) ;
}
else {
return methodInfo ;
}
}
return null ;
}
private RequestMappingInfo createFromRequestMapping ( RequestMapping annotation ) {
/ * *
* Override this method to create a { @link RequestMappingInfo } from a @ { @link RequestMapping } annotation . The main
* reason for doing so is to provide a custom { @link RequestCondition } to the RequestMappingInfo constructor .
*
* < p > This method is invoked both for type - and method - level @ { @link RequestMapping } annotations . The resulting
* { @link RequestMappingInfo } s are combined via { @link RequestMappingInfo # combine ( RequestMappingInfo ) } .
*
* @param annot a type - or a method - level { @link RequestMapping } annotation
* @param handlerType the handler type
* @param method the method with which the created RequestMappingInfo will be combined
* @return a { @link RequestMappingInfo } instance ; never { @code null }
* /
protected RequestMappingInfo createRequestMappingInfo ( RequestMapping annot , Class < ? > handlerType , Method method ) {
return new RequestMappingInfo (
new PatternsRequestCondition ( annotation . value ( ) , getUrlPathHelper ( ) , getPathMatcher ( ) ) ,
new RequestMethodsRequestCondition ( annotation . method ( ) ) ,
new ParamsRequestCondition ( annotation . params ( ) ) ,
new HeadersRequestCondition ( annotation . headers ( ) ) ,
new ConsumesRequestCondition ( annotation . consumes ( ) , annotation . headers ( ) ) ,
new ProducesRequestCondition ( annotation . produces ( ) , annotation . headers ( ) ) , null ) ;
new PatternsRequestCondition ( annot . value ( ) , getUrlPathHelper ( ) , getPathMatcher ( ) , useSuffixPatternMatch ) ,
new RequestMethodsRequestCondition ( annot . method ( ) ) ,
new ParamsRequestCondition ( annot . params ( ) ) ,
new HeadersRequestCondition ( annot . headers ( ) ) ,
new ConsumesRequestCondition ( annot . consumes ( ) , annot . headers ( ) ) ,
new ProducesRequestCondition ( annot . produces ( ) , annot . headers ( ) ) , null ) ;
}
}