@ -17,58 +17,48 @@
package org.springframework.web.servlet.handler ;
package org.springframework.web.servlet.handler ;
import java.util.Collections ;
import java.util.Collections ;
import java.util.Map ;
import java.util.stream.Stream ;
import org.junit.jupiter.api.Test ;
import org.junit.jupiter.api.Test ;
import org.junit.jupiter.params.ParameterizedTest ;
import org.junit.jupiter.params.ParameterizedTest ;
import org.junit.jupiter.params.provider.ValueSource ;
import org.junit.jupiter.params.provider.Arguments ;
import org.junit.jupiter.params.provider.MethodSource ;
import org.springframework.beans.FatalBeanException ;
import org.springframework.beans.factory.NoSuchBeanDefinitionException ;
import org.springframework.beans.factory.NoSuchBeanDefinitionException ;
import org.springframework.context.support.StaticApplicationContext ;
import org.springframework.context.support.StaticApplicationContext ;
import org.springframework.web.context.support.XmlWebApplicationContext ;
import org.springframework.http.HttpStatus ;
import org.springframework.util.Assert ;
import org.springframework.web.servlet.HandlerExecutionChain ;
import org.springframework.web.servlet.HandlerExecutionChain ;
import org.springframework.web.servlet.HandlerInterceptor ;
import org.springframework.web.servlet.HandlerInterceptor ;
import org.springframework.web.servlet.HandlerMapping ;
import org.springframework.web.servlet.HandlerMapping ;
import org.springframework.web.servlet.mvc.ParameterizableViewController ;
import org.springframework.web.servlet.view.RedirectView ;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest ;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest ;
import org.springframework.web.testfixture.servlet.MockServletContext ;
import org.springframework.web.util.UrlPathHelper ;
import org.springframework.web.util.UrlPathHelper ;
import org.springframework.web.util.WebUtils ;
import org.springframework.web.util.WebUtils ;
import static org.assertj.core.api.Assertions.assertThat ;
import static org.assertj.core.api.Assertions.assertThat ;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType ;
import static org.assertj.core.api.Assertions.assertThatThrownBy ;
import static org.springframework.web.servlet.HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE ;
import static org.springframework.web.servlet.HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE ;
import static org.springframework.web.servlet.HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ;
import static org.springframework.web.servlet.HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ;
import static org.springframework.web.servlet.HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE ;
/ * *
/ * *
* @author Rod Johnson
* Tests for { @link SimpleUrlHandlerMapping } .
* @author Juergen Hoeller
* @author Brian Clozel
* /
* /
class SimpleUrlHandlerMappingTests {
class SimpleUrlHandlerMappingTests {
@Test
@Test
void handlerBeanNotFound ( ) {
void shouldFailWhenHandlerBeanNotFound ( ) {
MockServletContext sc = new MockServletContext ( "" ) ;
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping ( Map . of ( "/welcome.html" , "mainController" ) ) ;
XmlWebApplicationContext root = new XmlWebApplicationContext ( ) ;
assertThatThrownBy ( ( ) - > handlerMapping . setApplicationContext ( new StaticApplicationContext ( ) ) )
root . setServletContext ( sc ) ;
. isInstanceOf ( NoSuchBeanDefinitionException . class ) ;
root . setConfigLocations ( "/org/springframework/web/servlet/handler/map1.xml" ) ;
root . refresh ( ) ;
XmlWebApplicationContext wac = new XmlWebApplicationContext ( ) ;
wac . setParent ( root ) ;
wac . setServletContext ( sc ) ;
wac . setNamespace ( "map2err" ) ;
wac . setConfigLocations ( "/org/springframework/web/servlet/handler/map2err.xml" ) ;
assertThatExceptionOfType ( FatalBeanException . class )
. isThrownBy ( wac : : refresh )
. withCauseInstanceOf ( NoSuchBeanDefinitionException . class )
. satisfies ( ex - > {
NoSuchBeanDefinitionException cause = ( NoSuchBeanDefinitionException ) ex . getCause ( ) ;
assertThat ( cause . getBeanName ( ) ) . isEqualTo ( "mainControlle" ) ;
} ) ;
}
}
@Test
@Test
void testNewlineInRequest ( ) throws Exception {
void newlineInRequestShouldMatch ( ) throws Exception {
Object controller = new Object ( ) ;
Object controller = new Object ( ) ;
UrlPathHelper urlPathHelper = new UrlPathHelper ( ) ;
UrlPathHelper urlPathHelper = new UrlPathHelper ( ) ;
urlPathHelper . setUrlDecode ( false ) ;
urlPathHelper . setUrlDecode ( false ) ;
@ -84,84 +74,143 @@ class SimpleUrlHandlerMappingTests {
}
}
@ParameterizedTest
@ParameterizedTest
@ValueSource ( strings = { "urlMapping" , "urlMappingWithProps" , "urlMappingWithPathPatterns" } )
@MethodSource ( "handlerMappings" )
void checkMappings ( String beanName ) throws Exception {
void resolveFromMap ( SimpleUrlHandlerMapping handlerMapping ) throws Exception {
MockServletContext sc = new MockServletContext ( "" ) ;
StaticApplicationContext applicationContext = new StaticApplicationContext ( ) ;
XmlWebApplicationContext wac = new XmlWebApplicationContext ( ) ;
applicationContext . registerSingleton ( "mainController" , Object . class ) ;
wac . setServletContext ( sc ) ;
Object mainController = applicationContext . getBean ( "mainController" ) ;
wac . setConfigLocations ( "/org/springframework/web/servlet/handler/map2.xml" ) ;
handlerMapping . setUrlMap ( Map . of ( "/welcome.html" , "mainController" ) ) ;
wac . refresh ( ) ;
handlerMapping . setApplicationContext ( applicationContext ) ;
Object bean = wac . getBean ( "mainController" ) ;
Object otherBean = wac . getBean ( "otherController" ) ;
boolean usePathPatterns = handlerMapping . getPatternParser ( ) ! = null ;
Object defaultBean = wac . getBean ( "starController" ) ;
HandlerMapping hm = ( HandlerMapping ) wac . getBean ( beanName ) ;
wac . close ( ) ;
boolean usePathPatterns = ( ( ( AbstractHandlerMapping ) hm ) . getPatternParser ( ) ! = null ) ;
MockHttpServletRequest request = PathPatternsTestUtils . initRequest ( "GET" , "/welcome.html" , usePathPatterns ) ;
MockHttpServletRequest request = PathPatternsTestUtils . initRequest ( "GET" , "/welcome.html" , usePathPatterns ) ;
HandlerExecutionChain chain = getHandler ( hm , request ) ;
HandlerExecutionChain chain = getHandler ( handlerMapping , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( bean ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "/welcome.html" ) ;
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( bean ) ;
request = PathPatternsTestUtils . initRequest ( "GET" , "/welcome.x;jsessionid=123" , usePathPatterns ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( mainController ) ;
chain = getHandler ( hm , request ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "/welcome.html" ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( otherBean ) ;
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( mainController ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "welcome.x" ) ;
}
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( otherBean ) ;
request = PathPatternsTestUtils . initRequest ( "GET" , "/app" , "/welcome.x" , usePathPatterns ) ;
@ParameterizedTest
chain = getHandler ( hm , request ) ;
@MethodSource ( "handlerMappings" )
assertThat ( chain . getHandler ( ) ) . isSameAs ( otherBean ) ;
void resolvePatternFromMap ( SimpleUrlHandlerMapping handlerMapping ) throws Exception {
StaticApplicationContext applicationContext = new StaticApplicationContext ( ) ;
applicationContext . registerSingleton ( "mainController" , Object . class ) ;
Object mainController = applicationContext . getBean ( "mainController" ) ;
handlerMapping . setUrlMap ( Map . of ( "/welcome*" , "mainController" ) ) ;
handlerMapping . setApplicationContext ( applicationContext ) ;
boolean usePathPatterns = handlerMapping . getPatternParser ( ) ! = null ;
MockHttpServletRequest request = PathPatternsTestUtils . initRequest ( "GET" , "/welcome.x" , usePathPatterns ) ;
HandlerExecutionChain chain = getHandler ( handlerMapping , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( mainController ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "welcome.x" ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "welcome.x" ) ;
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( otherBean ) ;
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( mainController ) ;
}
request = PathPatternsTestUtils . initRequest ( "GET" , "/" , usePathPatterns ) ;
request . setServletPath ( "/welcome.html" ) ;
chain = getHandler ( hm , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( bean ) ;
request = PathPatternsTestUtils . initRequest ( "GET" , "/app" , "/welcome.html" , usePathPatterns ) ;
chain = getHandler ( hm , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( bean ) ;
request = PathPatternsTestUtils . initRequest ( "GET" , "/show.html" , usePathPatterns ) ;
chain = getHandler ( hm , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( bean ) ;
request = PathPatternsTestUtils . initRequest ( "GET" , "/bookseats.html" , usePathPatterns ) ;
chain = getHandler ( hm , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( bean ) ;
request = PathPatternsTestUtils . initRequest ( "GET" , null , "/original-welcome.html" , usePathPatterns ,
@ParameterizedTest
req - > req . setAttribute ( WebUtils . INCLUDE_REQUEST_URI_ATTRIBUTE , "/welcome.html" ) ) ;
@MethodSource ( "handlerMappings" )
chain = getHandler ( hm , request ) ;
void resolvePathWithParamFromMap ( SimpleUrlHandlerMapping handlerMapping ) throws Exception {
assertThat ( chain . getHandler ( ) ) . isSameAs ( bean ) ;
StaticApplicationContext applicationContext = new StaticApplicationContext ( ) ;
applicationContext . registerSingleton ( "mainController" , Object . class ) ;
Object mainController = applicationContext . getBean ( "mainController" ) ;
handlerMapping . setUrlMap ( Map . of ( "/welcome.x" , "mainController" ) ) ;
handlerMapping . setApplicationContext ( applicationContext ) ;
boolean usePathPatterns = handlerMapping . getPatternParser ( ) ! = null ;
MockHttpServletRequest request = PathPatternsTestUtils . initRequest ( "GET" , "/welcome.x;jsessionid=123" , usePathPatterns ) ;
HandlerExecutionChain chain = getHandler ( handlerMapping , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( mainController ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "/welcome.x" ) ;
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( mainController ) ;
}
request = PathPatternsTestUtils . initRequest ( "GET" , null , "/original-show.html" , usePathPatterns ,
@ParameterizedTest
req - > req . setAttribute ( WebUtils . INCLUDE_REQUEST_URI_ATTRIBUTE , "/show.html" ) ) ;
@MethodSource ( "handlerMappings" )
chain = getHandler ( hm , request ) ;
void resolvePathWithContextFromMap ( SimpleUrlHandlerMapping handlerMapping ) throws Exception {
assertThat ( chain . getHandler ( ) ) . isSameAs ( bean ) ;
StaticApplicationContext applicationContext = new StaticApplicationContext ( ) ;
applicationContext . registerSingleton ( "mainController" , Object . class ) ;
Object mainController = applicationContext . getBean ( "mainController" ) ;
handlerMapping . setUrlMap ( Map . of ( "/welcome.x" , "mainController" ) ) ;
handlerMapping . setApplicationContext ( applicationContext ) ;
boolean usePathPatterns = handlerMapping . getPatternParser ( ) ! = null ;
MockHttpServletRequest request = PathPatternsTestUtils . initRequest ( "GET" , "/app" , "/welcome.x" , usePathPatterns ) ;
HandlerExecutionChain chain = getHandler ( handlerMapping , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( mainController ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "/welcome.x" ) ;
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( mainController ) ;
}
request = PathPatternsTestUtils . initRequest ( "GET" , null , "/original-bookseats.html" , usePathPatterns ,
@ParameterizedTest
req - > req . setAttribute ( WebUtils . INCLUDE_REQUEST_URI_ATTRIBUTE , "/bookseats.html" ) ) ;
@MethodSource ( "handlerMappings" )
chain = getHandler ( hm , request ) ;
void resolvePathWithIncludeFromMap ( SimpleUrlHandlerMapping handlerMapping ) throws Exception {
assertThat ( chain . getHandler ( ) ) . isSameAs ( bean ) ;
StaticApplicationContext applicationContext = new StaticApplicationContext ( ) ;
applicationContext . registerSingleton ( "mainController" , Object . class ) ;
Object mainController = applicationContext . getBean ( "mainController" ) ;
handlerMapping . setUrlMap ( Map . of ( "/welcome.html" , "mainController" ) ) ;
handlerMapping . setApplicationContext ( applicationContext ) ;
boolean usePathPatterns = handlerMapping . getPatternParser ( ) ! = null ;
MockHttpServletRequest request = PathPatternsTestUtils . initRequest ( "GET" , "/original.html" , usePathPatterns ) ;
request . setAttribute ( WebUtils . INCLUDE_REQUEST_URI_ATTRIBUTE , "/welcome.html" ) ;
HandlerExecutionChain chain = getHandler ( handlerMapping , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( mainController ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "/welcome.html" ) ;
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( mainController ) ;
}
request = PathPatternsTestUtils . initRequest ( "GET" , "/" , usePathPatterns ) ;
@ParameterizedTest
chain = getHandler ( hm , request ) ;
@MethodSource ( "handlerMappings" )
assertThat ( chain . getHandler ( ) ) . isSameAs ( bean ) ;
void resolveDefaultPathFromMap ( SimpleUrlHandlerMapping handlerMapping ) throws Exception {
StaticApplicationContext applicationContext = new StaticApplicationContext ( ) ;
applicationContext . registerSingleton ( "mainController" , Object . class ) ;
Object mainController = applicationContext . getBean ( "mainController" ) ;
handlerMapping . setDefaultHandler ( mainController ) ;
handlerMapping . setApplicationContext ( applicationContext ) ;
boolean usePathPatterns = handlerMapping . getPatternParser ( ) ! = null ;
MockHttpServletRequest request = PathPatternsTestUtils . initRequest ( "GET" , "/" , usePathPatterns ) ;
HandlerExecutionChain chain = getHandler ( handlerMapping , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( mainController ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "/" ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "/" ) ;
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( mainController ) ;
}
@ParameterizedTest
@MethodSource ( "handlerMappings" )
void resolveParameterizedControllerFromMap ( SimpleUrlHandlerMapping handlerMapping ) throws Exception {
ParameterizableViewController viewController = new ParameterizableViewController ( ) ;
viewController . setView ( new RedirectView ( "/after/{variable}" ) ) ;
viewController . setStatusCode ( HttpStatus . PERMANENT_REDIRECT ) ;
handlerMapping . setUrlMap ( Map . of ( "/before/{variable}" , viewController ) ) ;
handlerMapping . setApplicationContext ( new StaticApplicationContext ( ) ) ;
boolean usePathPatterns = handlerMapping . getPatternParser ( ) ! = null ;
MockHttpServletRequest request = PathPatternsTestUtils . initRequest ( "GET" , "/before/test" , usePathPatterns ) ;
HandlerExecutionChain chain = getHandler ( handlerMapping , request ) ;
assertThat ( chain . getHandler ( ) ) . isSameAs ( viewController ) ;
Map < String , String > variables = ( Map < String , String > ) request . getAttribute ( URI_TEMPLATE_VARIABLES_ATTRIBUTE ) ;
assertThat ( variables ) . containsEntry ( "variable" , "test" ) ;
assertThat ( request . getAttribute ( BEST_MATCHING_HANDLER_ATTRIBUTE ) ) . isEqualTo ( viewController ) ;
}
request = PathPatternsTestUtils . initRequest ( "GET" , "/somePath" , usePathPatterns ) ;
static Stream < Arguments > handlerMappings ( ) {
chain = getHandler ( hm , request ) ;
SimpleUrlHandlerMapping defaultConfig = new SimpleUrlHandlerMapping ( ) ;
assertThat ( chain . getHandler ( ) ) . as ( "Handler is correct bean" ) . isSameAs ( defaultBean ) ;
SimpleUrlHandlerMapping antPatternConfig = new SimpleUrlHandlerMapping ( ) ;
assertThat ( request . getAttribute ( PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE ) ) . isEqualTo ( "/somePath" ) ;
antPatternConfig . setPatternParser ( null ) ;
return Stream . of ( Arguments . of ( defaultConfig , "with PathPattern" ) , Arguments . of ( antPatternConfig , "with AntPathMatcher" ) ) ;
}
}
private HandlerExecutionChain getHandler ( HandlerMapping mapping , MockHttpServletRequest request ) throws Exception {
private HandlerExecutionChain getHandler ( HandlerMapping mapping , MockHttpServletRequest request ) throws Exception {
HandlerExecutionChain chain = mapping . getHandler ( request ) ;
HandlerExecutionChain chain = mapping . getHandler ( request ) ;
Assert . notNull ( chain , "No handler found for request: " + request . getRequestURI ( ) ) ;
for ( HandlerInterceptor interceptor : chain . getInterceptorList ( ) ) {
for ( HandlerInterceptor interceptor : chain . getInterceptorList ( ) ) {
interceptor . preHandle ( request , null , chain . getHandler ( ) ) ;
interceptor . preHandle ( request , null , chain . getHandler ( ) ) ;
}
}