Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
fddc9e9c
Commit
fddc9e9c
authored
Jun 28, 2018
by
Madhura Bhave
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support multiple paths in DispatcherServletPathProvider
Closes gh-13603
parent
43ea78f2
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
198 additions
and
74 deletions
+198
-74
ServletEndpointManagementContextConfiguration.java
...nt/web/ServletEndpointManagementContextConfiguration.java
+22
-5
EndpointRequest.java
...tuate/autoconfigure/security/servlet/EndpointRequest.java
+30
-26
WebMvcEndpointChildContextConfiguration.java
.../web/servlet/WebMvcEndpointChildContextConfiguration.java
+3
-1
ServletEndpointManagementContextConfigurationTests.java
...b/ServletEndpointManagementContextConfigurationTests.java
+18
-5
EndpointRequestTests.java
.../autoconfigure/security/servlet/EndpointRequestTests.java
+22
-19
WebMvcEndpointChildContextConfigurationTests.java
...servlet/WebMvcEndpointChildContextConfigurationTests.java
+2
-2
ServletEndpointRegistrar.java
...k/boot/actuate/endpoint/web/ServletEndpointRegistrar.java
+26
-6
ServletEndpointRegistrarTests.java
...t/actuate/endpoint/web/ServletEndpointRegistrarTests.java
+63
-2
DispatcherServletAutoConfiguration.java
...igure/web/servlet/DispatcherServletAutoConfiguration.java
+4
-2
DispatcherServletPathProvider.java
...oconfigure/web/servlet/DispatcherServletPathProvider.java
+5
-3
DispatcherServletAutoConfigurationTests.java
.../web/servlet/DispatcherServletAutoConfigurationTests.java
+3
-3
No files found.
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.java
View file @
fddc9e9c
...
@@ -16,6 +16,9 @@
...
@@ -16,6 +16,9 @@
package
org
.
springframework
.
boot
.
actuate
.
autoconfigure
.
endpoint
.
web
;
package
org
.
springframework
.
boot
.
actuate
.
autoconfigure
.
endpoint
.
web
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
org.glassfish.jersey.server.ResourceConfig
;
import
org.glassfish.jersey.server.ResourceConfig
;
import
org.springframework.boot.actuate.autoconfigure.endpoint.ExposeExcludePropertyEndpointFilter
;
import
org.springframework.boot.actuate.autoconfigure.endpoint.ExposeExcludePropertyEndpointFilter
;
...
@@ -31,6 +34,7 @@ import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPathP
...
@@ -31,6 +34,7 @@ import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPathP
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.servlet.DispatcherServlet
;
import
org.springframework.web.servlet.DispatcherServlet
;
/**
/**
...
@@ -70,14 +74,27 @@ public class ServletEndpointManagementContextConfiguration {
...
@@ -70,14 +74,27 @@ public class ServletEndpointManagementContextConfiguration {
ServletEndpointsSupplier
servletEndpointsSupplier
)
{
ServletEndpointsSupplier
servletEndpointsSupplier
)
{
DispatcherServletPathProvider
servletPathProvider
=
this
.
context
DispatcherServletPathProvider
servletPathProvider
=
this
.
context
.
getBean
(
DispatcherServletPathProvider
.
class
);
.
getBean
(
DispatcherServletPathProvider
.
class
);
String
servletPath
=
servletPathProvider
.
getServletPath
();
Set
<
String
>
cleanedPaths
=
getServletPaths
(
properties
,
servletPathProvider
);
if
(
servletPath
.
equals
(
"/"
))
{
return
new
ServletEndpointRegistrar
(
cleanedPaths
,
servletPath
=
""
;
}
return
new
ServletEndpointRegistrar
(
servletPath
+
properties
.
getBasePath
(),
servletEndpointsSupplier
.
getEndpoints
());
servletEndpointsSupplier
.
getEndpoints
());
}
}
private
Set
<
String
>
getServletPaths
(
WebEndpointProperties
properties
,
DispatcherServletPathProvider
servletPathProvider
)
{
Set
<
String
>
servletPaths
=
servletPathProvider
.
getServletPaths
();
return
servletPaths
.
stream
().
map
((
p
)
->
{
String
path
=
cleanServletPath
(
p
);
return
path
+
properties
.
getBasePath
();
}).
collect
(
Collectors
.
toSet
());
}
private
String
cleanServletPath
(
String
servletPath
)
{
if
(
StringUtils
.
hasText
(
servletPath
)
&&
servletPath
.
endsWith
(
"/"
))
{
return
servletPath
.
substring
(
0
,
servletPath
.
length
()
-
1
);
}
return
servletPath
;
}
}
}
@Configuration
@Configuration
...
...
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java
View file @
fddc9e9c
...
@@ -137,10 +137,9 @@ public final class EndpointRequest {
...
@@ -137,10 +137,9 @@ public final class EndpointRequest {
private
RequestMatcher
createDelegate
(
WebApplicationContext
context
)
{
private
RequestMatcher
createDelegate
(
WebApplicationContext
context
)
{
try
{
try
{
String
servletPath
=
getServletPath
(
context
);
Set
<
String
>
servletPaths
=
getServletPaths
(
context
);
RequestMatcherFactory
requestMatcherFactory
=
(
StringUtils
RequestMatcherFactory
requestMatcherFactory
=
new
RequestMatcherFactory
(
.
hasText
(
servletPath
)
?
new
RequestMatcherFactory
(
servletPath
)
servletPaths
);
:
RequestMatcherFactory
.
withEmptyServletPath
());
return
createDelegate
(
context
,
requestMatcherFactory
);
return
createDelegate
(
context
,
requestMatcherFactory
);
}
}
catch
(
NoSuchBeanDefinitionException
ex
)
{
catch
(
NoSuchBeanDefinitionException
ex
)
{
...
@@ -148,13 +147,13 @@ public final class EndpointRequest {
...
@@ -148,13 +147,13 @@ public final class EndpointRequest {
}
}
}
}
private
S
tring
getServletPath
(
WebApplicationContext
context
)
{
private
S
et
<
String
>
getServletPaths
(
WebApplicationContext
context
)
{
try
{
try
{
return
context
.
getBean
(
DispatcherServletPathProvider
.
class
)
return
context
.
getBean
(
DispatcherServletPathProvider
.
class
)
.
getServletPath
();
.
getServletPath
s
();
}
}
catch
(
NoSuchBeanDefinitionException
ex
)
{
catch
(
NoSuchBeanDefinitionException
ex
)
{
return
""
;
return
Collections
.
singleton
(
""
)
;
}
}
}
}
...
@@ -226,7 +225,7 @@ public final class EndpointRequest {
...
@@ -226,7 +225,7 @@ public final class EndpointRequest {
requestMatcherFactory
,
paths
);
requestMatcherFactory
,
paths
);
if
(
this
.
includeLinks
if
(
this
.
includeLinks
&&
StringUtils
.
hasText
(
pathMappedEndpoints
.
getBasePath
()))
{
&&
StringUtils
.
hasText
(
pathMappedEndpoints
.
getBasePath
()))
{
delegateMatchers
.
add
(
delegateMatchers
.
add
All
(
requestMatcherFactory
.
antPath
(
pathMappedEndpoints
.
getBasePath
()));
requestMatcherFactory
.
antPath
(
pathMappedEndpoints
.
getBasePath
()));
}
}
return
new
OrRequestMatcher
(
delegateMatchers
);
return
new
OrRequestMatcher
(
delegateMatchers
);
...
@@ -259,7 +258,8 @@ public final class EndpointRequest {
...
@@ -259,7 +258,8 @@ public final class EndpointRequest {
private
List
<
RequestMatcher
>
getDelegateMatchers
(
private
List
<
RequestMatcher
>
getDelegateMatchers
(
RequestMatcherFactory
requestMatcherFactory
,
Set
<
String
>
paths
)
{
RequestMatcherFactory
requestMatcherFactory
,
Set
<
String
>
paths
)
{
return
paths
.
stream
()
return
paths
.
stream
()
.
map
((
path
)
->
requestMatcherFactory
.
antPath
(
path
,
"/**"
))
.
flatMap
(
(
path
)
->
requestMatcherFactory
.
antPath
(
path
,
"/**"
).
stream
())
.
collect
(
Collectors
.
toList
());
.
collect
(
Collectors
.
toList
());
}
}
...
@@ -276,7 +276,9 @@ public final class EndpointRequest {
...
@@ -276,7 +276,9 @@ public final class EndpointRequest {
WebEndpointProperties
properties
=
context
WebEndpointProperties
properties
=
context
.
getBean
(
WebEndpointProperties
.
class
);
.
getBean
(
WebEndpointProperties
.
class
);
if
(
StringUtils
.
hasText
(
properties
.
getBasePath
()))
{
if
(
StringUtils
.
hasText
(
properties
.
getBasePath
()))
{
return
requestMatcherFactory
.
antPath
(
properties
.
getBasePath
());
List
<
RequestMatcher
>
matchers
=
requestMatcherFactory
.
antPath
(
properties
.
getBasePath
());
return
new
OrRequestMatcher
(
matchers
);
}
}
return
EMPTY_MATCHER
;
return
EMPTY_MATCHER
;
}
}
...
@@ -288,25 +290,27 @@ public final class EndpointRequest {
...
@@ -288,25 +290,27 @@ public final class EndpointRequest {
*/
*/
private
static
class
RequestMatcherFactory
{
private
static
class
RequestMatcherFactory
{
private
final
String
servletPath
;
private
final
Set
<
String
>
servletPaths
=
new
LinkedHashSet
<>();
private
static
final
RequestMatcherFactory
EMPTY_SERVLET_PATH
=
new
RequestMatcherFactory
(
""
);
RequestMatcherFactory
(
String
servletPath
)
{
this
.
servletPath
=
servletPath
;
}
RequestMatcher
antPath
(
String
...
parts
)
{
RequestMatcherFactory
(
Set
<
String
>
servletPaths
)
{
String
pattern
=
(
this
.
servletPath
.
equals
(
"/"
)
?
""
:
this
.
servletPath
);
this
.
servletPaths
.
addAll
(
servletPaths
);
for
(
String
part
:
parts
)
{
pattern
+=
part
;
}
return
new
AntPathRequestMatcher
(
pattern
);
}
}
static
RequestMatcherFactory
withEmptyServletPath
()
{
List
<
RequestMatcher
>
antPath
(
String
...
parts
)
{
return
EMPTY_SERVLET_PATH
;
List
<
RequestMatcher
>
matchers
=
new
ArrayList
<>();
this
.
servletPaths
.
stream
().
map
((
p
)
->
{
if
(
StringUtils
.
hasText
(
p
))
{
return
p
;
}
return
""
;
}).
distinct
().
forEach
((
path
)
->
{
String
pattern
=
(
path
.
equals
(
"/"
)
?
""
:
path
);
for
(
String
part
:
parts
)
{
pattern
+=
part
;
}
matchers
.
add
(
new
AntPathRequestMatcher
(
pattern
));
});
return
matchers
;
}
}
}
}
...
...
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfiguration.java
View file @
fddc9e9c
...
@@ -16,6 +16,8 @@
...
@@ -16,6 +16,8 @@
package
org
.
springframework
.
boot
.
actuate
.
autoconfigure
.
web
.
servlet
;
package
org
.
springframework
.
boot
.
actuate
.
autoconfigure
.
web
.
servlet
;
import
java.util.Collections
;
import
org.springframework.beans.factory.ListableBeanFactory
;
import
org.springframework.beans.factory.ListableBeanFactory
;
import
org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration
;
import
org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration
;
import
org.springframework.boot.actuate.autoconfigure.web.ManagementContextType
;
import
org.springframework.boot.actuate.autoconfigure.web.ManagementContextType
;
...
@@ -95,7 +97,7 @@ class WebMvcEndpointChildContextConfiguration {
...
@@ -95,7 +97,7 @@ class WebMvcEndpointChildContextConfiguration {
@Bean
@Bean
public
DispatcherServletPathProvider
childDispatcherServletPathProvider
()
{
public
DispatcherServletPathProvider
childDispatcherServletPathProvider
()
{
return
()
->
""
;
return
()
->
Collections
.
singleton
(
""
)
;
}
}
}
}
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfigurationTests.java
View file @
fddc9e9c
...
@@ -17,6 +17,8 @@
...
@@ -17,6 +17,8 @@
package
org
.
springframework
.
boot
.
actuate
.
autoconfigure
.
endpoint
.
web
;
package
org
.
springframework
.
boot
.
actuate
.
autoconfigure
.
endpoint
.
web
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.LinkedHashSet
;
import
java.util.Set
;
import
org.glassfish.jersey.server.ResourceConfig
;
import
org.glassfish.jersey.server.ResourceConfig
;
import
org.junit.Test
;
import
org.junit.Test
;
...
@@ -48,18 +50,22 @@ public class ServletEndpointManagementContextConfigurationTests {
...
@@ -48,18 +50,22 @@ public class ServletEndpointManagementContextConfigurationTests {
.
withUserConfiguration
(
TestConfig
.
class
);
.
withUserConfiguration
(
TestConfig
.
class
);
@Test
@Test
@SuppressWarnings
(
"unchecked"
)
public
void
contextShouldContainServletEndpointRegistrar
()
{
public
void
contextShouldContainServletEndpointRegistrar
()
{
FilteredClassLoader
classLoader
=
new
FilteredClassLoader
(
ResourceConfig
.
class
);
FilteredClassLoader
classLoader
=
new
FilteredClassLoader
(
ResourceConfig
.
class
);
this
.
contextRunner
.
withClassLoader
(
classLoader
).
run
((
context
)
->
{
this
.
contextRunner
.
withClassLoader
(
classLoader
).
run
((
context
)
->
{
assertThat
(
context
).
hasSingleBean
(
ServletEndpointRegistrar
.
class
);
assertThat
(
context
).
hasSingleBean
(
ServletEndpointRegistrar
.
class
);
ServletEndpointRegistrar
bean
=
context
ServletEndpointRegistrar
bean
=
context
.
getBean
(
ServletEndpointRegistrar
.
class
);
.
getBean
(
ServletEndpointRegistrar
.
class
);
String
basePath
=
(
String
)
ReflectionTestUtils
.
getField
(
bean
,
"basePath"
);
Set
<
String
>
basePaths
=
(
Set
<
String
>)
ReflectionTestUtils
.
getField
(
bean
,
assertThat
(
basePath
).
isEqualTo
(
"/test/actuator"
);
"basePaths"
);
assertThat
(
basePaths
).
containsExactlyInAnyOrder
(
"/test/actuator"
,
"/actuator"
,
"/foo/actuator"
);
});
});
}
}
@Test
@Test
@SuppressWarnings
(
"unchecked"
)
public
void
servletPathShouldNotAffectJerseyConfiguration
()
{
public
void
servletPathShouldNotAffectJerseyConfiguration
()
{
FilteredClassLoader
classLoader
=
new
FilteredClassLoader
(
FilteredClassLoader
classLoader
=
new
FilteredClassLoader
(
DispatcherServlet
.
class
);
DispatcherServlet
.
class
);
...
@@ -67,8 +73,9 @@ public class ServletEndpointManagementContextConfigurationTests {
...
@@ -67,8 +73,9 @@ public class ServletEndpointManagementContextConfigurationTests {
assertThat
(
context
).
hasSingleBean
(
ServletEndpointRegistrar
.
class
);
assertThat
(
context
).
hasSingleBean
(
ServletEndpointRegistrar
.
class
);
ServletEndpointRegistrar
bean
=
context
ServletEndpointRegistrar
bean
=
context
.
getBean
(
ServletEndpointRegistrar
.
class
);
.
getBean
(
ServletEndpointRegistrar
.
class
);
String
basePath
=
(
String
)
ReflectionTestUtils
.
getField
(
bean
,
"basePath"
);
Set
<
String
>
basePaths
=
(
Set
<
String
>)
ReflectionTestUtils
.
getField
(
bean
,
assertThat
(
basePath
).
isEqualTo
(
"/actuator"
);
"basePaths"
);
assertThat
(
basePaths
).
containsExactly
(
"/actuator"
);
});
});
}
}
...
@@ -91,7 +98,13 @@ public class ServletEndpointManagementContextConfigurationTests {
...
@@ -91,7 +98,13 @@ public class ServletEndpointManagementContextConfigurationTests {
@Bean
@Bean
public
DispatcherServletPathProvider
servletPathProvider
()
{
public
DispatcherServletPathProvider
servletPathProvider
()
{
return
()
->
"/test"
;
return
()
->
{
Set
<
String
>
paths
=
new
LinkedHashSet
<>();
paths
.
add
(
"/"
);
paths
.
add
(
"/test"
);
paths
.
add
(
"/foo/"
);
return
paths
;
};
}
}
}
}
...
...
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java
View file @
fddc9e9c
...
@@ -17,6 +17,8 @@
...
@@ -17,6 +17,8 @@
package
org
.
springframework
.
boot
.
actuate
.
autoconfigure
.
security
.
servlet
;
package
org
.
springframework
.
boot
.
actuate
.
autoconfigure
.
security
.
servlet
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.List
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
...
@@ -76,23 +78,23 @@ public class EndpointRequestTests {
...
@@ -76,23 +78,23 @@ public class EndpointRequestTests {
@Test
@Test
public
void
toAnyEndpointWhenServletPathNotEmptyShouldMatch
()
{
public
void
toAnyEndpointWhenServletPathNotEmptyShouldMatch
()
{
RequestMatcher
matcher
=
EndpointRequest
.
toAnyEndpoint
();
RequestMatcher
matcher
=
EndpointRequest
.
toAnyEndpoint
();
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
).
matches
(
"/spring
"
,
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
,
"/admin"
).
matches
(
"/actuator/foo
"
,
"/
actuator/foo
"
);
"/
spring"
,
"/admin
"
);
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
).
matches
(
"/spring
"
,
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
,
"/admin"
).
matches
(
"/actuator/bar
"
,
"/
actuator/bar
"
);
"/
spring"
,
"/admin
"
);
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
).
matches
(
"/
spring"
,
"/actuator
"
);
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
).
matches
(
"/
actuator"
,
"/spring
"
);
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
).
doesNotMatch
(
"/
spring
"
,
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
).
doesNotMatch
(
"/
actuator/baz
"
,
"/
actuator/baz
"
);
"/
spring
"
);
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
).
doesNotMatch
(
"
"
,
"/actuator/foo
"
);
assertMatcher
(
matcher
,
"/actuator"
,
"/spring"
).
doesNotMatch
(
"
/actuator/foo"
,
"
"
);
}
}
@Test
@Test
public
void
toAnyEndpointWhenDispatcherServletPathProviderNotAvailableUsesEmptyPath
()
{
public
void
toAnyEndpointWhenDispatcherServletPathProviderNotAvailableUsesEmptyPath
()
{
RequestMatcher
matcher
=
EndpointRequest
.
toAnyEndpoint
();
RequestMatcher
matcher
=
EndpointRequest
.
toAnyEndpoint
();
assertMatcher
(
matcher
,
"/actuator"
,
null
).
matches
(
"/actuator/foo"
);
assertMatcher
(
matcher
,
"/actuator"
,
(
String
)
null
).
matches
(
"/actuator/foo"
);
assertMatcher
(
matcher
,
"/actuator"
,
null
).
matches
(
"/actuator/bar"
);
assertMatcher
(
matcher
,
"/actuator"
,
(
String
)
null
).
matches
(
"/actuator/bar"
);
assertMatcher
(
matcher
,
"/actuator"
,
null
).
matches
(
"/actuator"
);
assertMatcher
(
matcher
,
"/actuator"
,
(
String
)
null
).
matches
(
"/actuator"
);
assertMatcher
(
matcher
,
"/actuator"
,
null
).
doesNotMatch
(
"/actuator/baz"
);
assertMatcher
(
matcher
,
"/actuator"
,
(
String
)
null
).
doesNotMatch
(
"/actuator/baz"
);
}
}
@Test
@Test
...
@@ -219,8 +221,8 @@ public class EndpointRequestTests {
...
@@ -219,8 +221,8 @@ public class EndpointRequestTests {
}
}
private
RequestMatcherAssert
assertMatcher
(
RequestMatcher
matcher
,
String
basePath
,
private
RequestMatcherAssert
assertMatcher
(
RequestMatcher
matcher
,
String
basePath
,
String
servletPath
)
{
String
...
servletPaths
)
{
return
assertMatcher
(
matcher
,
mockPathMappedEndpoints
(
basePath
),
servletPath
);
return
assertMatcher
(
matcher
,
mockPathMappedEndpoints
(
basePath
),
servletPath
s
);
}
}
private
PathMappedEndpoints
mockPathMappedEndpoints
(
String
basePath
)
{
private
PathMappedEndpoints
mockPathMappedEndpoints
(
String
basePath
)
{
...
@@ -243,7 +245,7 @@ public class EndpointRequestTests {
...
@@ -243,7 +245,7 @@ public class EndpointRequestTests {
}
}
private
RequestMatcherAssert
assertMatcher
(
RequestMatcher
matcher
,
private
RequestMatcherAssert
assertMatcher
(
RequestMatcher
matcher
,
PathMappedEndpoints
pathMappedEndpoints
,
String
servletPath
)
{
PathMappedEndpoints
pathMappedEndpoints
,
String
...
servletPaths
)
{
StaticWebApplicationContext
context
=
new
StaticWebApplicationContext
();
StaticWebApplicationContext
context
=
new
StaticWebApplicationContext
();
context
.
registerBean
(
WebEndpointProperties
.
class
);
context
.
registerBean
(
WebEndpointProperties
.
class
);
if
(
pathMappedEndpoints
!=
null
)
{
if
(
pathMappedEndpoints
!=
null
)
{
...
@@ -254,8 +256,9 @@ public class EndpointRequestTests {
...
@@ -254,8 +256,9 @@ public class EndpointRequestTests {
properties
.
setBasePath
(
pathMappedEndpoints
.
getBasePath
());
properties
.
setBasePath
(
pathMappedEndpoints
.
getBasePath
());
}
}
}
}
if
(
servletPath
!=
null
)
{
if
(
servletPaths
!=
null
)
{
DispatcherServletPathProvider
pathProvider
=
()
->
servletPath
;
DispatcherServletPathProvider
pathProvider
=
()
->
new
LinkedHashSet
<>(
Arrays
.
asList
(
servletPaths
));
context
.
registerBean
(
DispatcherServletPathProvider
.
class
,
()
->
pathProvider
);
context
.
registerBean
(
DispatcherServletPathProvider
.
class
,
()
->
pathProvider
);
}
}
return
assertThat
(
new
RequestMatcherAssert
(
context
,
matcher
));
return
assertThat
(
new
RequestMatcherAssert
(
context
,
matcher
));
...
@@ -276,8 +279,8 @@ public class EndpointRequestTests {
...
@@ -276,8 +279,8 @@ public class EndpointRequestTests {
matches
(
mockRequest
(
servletPath
));
matches
(
mockRequest
(
servletPath
));
}
}
public
void
matches
(
String
servletPath
,
String
pathInfo
)
{
public
void
matches
(
String
pathInfo
,
String
...
servletPaths
)
{
matches
(
mockRequest
(
servletPath
,
pathInfo
));
Arrays
.
stream
(
servletPaths
).
forEach
((
p
)
->
matches
(
mockRequest
(
p
,
pathInfo
)
));
}
}
private
void
matches
(
HttpServletRequest
request
)
{
private
void
matches
(
HttpServletRequest
request
)
{
...
...
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/servlet/WebMvcEndpointChildContextConfigurationTests.java
View file @
fddc9e9c
...
@@ -68,8 +68,8 @@ public class WebMvcEndpointChildContextConfigurationTests {
...
@@ -68,8 +68,8 @@ public class WebMvcEndpointChildContextConfigurationTests {
this
.
contextRunner
this
.
contextRunner
.
withUserConfiguration
(
WebMvcEndpointChildContextConfiguration
.
class
)
.
withUserConfiguration
(
WebMvcEndpointChildContextConfiguration
.
class
)
.
run
((
context
)
->
assertThat
(
context
.
run
((
context
)
->
assertThat
(
context
.
getBean
(
DispatcherServletPathProvider
.
class
).
getServletPath
())
.
getBean
(
DispatcherServletPathProvider
.
class
).
getServletPath
s
())
.
isEmpty
(
));
.
containsExactly
(
""
));
}
}
static
class
ExistingConfig
{
static
class
ExistingConfig
{
...
...
spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/ServletEndpointRegistrar.java
View file @
fddc9e9c
...
@@ -17,6 +17,8 @@
...
@@ -17,6 +17,8 @@
package
org
.
springframework
.
boot
.
actuate
.
endpoint
.
web
;
package
org
.
springframework
.
boot
.
actuate
.
endpoint
.
web
;
import
java.util.Collection
;
import
java.util.Collection
;
import
java.util.LinkedHashSet
;
import
java.util.Set
;
import
javax.servlet.ServletContext
;
import
javax.servlet.ServletContext
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletException
;
...
@@ -27,26 +29,38 @@ import org.apache.commons.logging.LogFactory;
...
@@ -27,26 +29,38 @@ import org.apache.commons.logging.LogFactory;
import
org.springframework.boot.web.servlet.ServletContextInitializer
;
import
org.springframework.boot.web.servlet.ServletContextInitializer
;
import
org.springframework.util.Assert
;
import
org.springframework.util.Assert
;
import
org.springframework.util.CollectionUtils
;
/**
/**
* {@link ServletContextInitializer} to register {@link ExposableServletEndpoint servlet
* {@link ServletContextInitializer} to register {@link ExposableServletEndpoint servlet
* endpoints}.
* endpoints}.
*
*
* @author Phillip Webb
* @author Phillip Webb
* @author Madhura Bhave
* @since 2.0.0
* @since 2.0.0
*/
*/
public
class
ServletEndpointRegistrar
implements
ServletContextInitializer
{
public
class
ServletEndpointRegistrar
implements
ServletContextInitializer
{
private
static
final
Log
logger
=
LogFactory
.
getLog
(
ServletEndpointRegistrar
.
class
);
private
static
final
Log
logger
=
LogFactory
.
getLog
(
ServletEndpointRegistrar
.
class
);
private
final
S
tring
basePath
;
private
final
S
et
<
String
>
basePaths
=
new
LinkedHashSet
<>()
;
private
final
Collection
<
ExposableServletEndpoint
>
servletEndpoints
;
private
final
Collection
<
ExposableServletEndpoint
>
servletEndpoints
;
public
ServletEndpointRegistrar
(
String
basePath
,
public
ServletEndpointRegistrar
(
String
basePath
,
Collection
<
ExposableServletEndpoint
>
servletEndpoints
)
{
Collection
<
ExposableServletEndpoint
>
servletEndpoints
)
{
Assert
.
notNull
(
servletEndpoints
,
"ServletEndpoints must not be null"
);
Assert
.
notNull
(
servletEndpoints
,
"ServletEndpoints must not be null"
);
this
.
basePath
=
(
basePath
!=
null
?
basePath
:
""
);
this
.
basePaths
.
add
((
basePath
!=
null
?
basePath
:
""
));
this
.
servletEndpoints
=
servletEndpoints
;
}
public
ServletEndpointRegistrar
(
Set
<
String
>
basePaths
,
Collection
<
ExposableServletEndpoint
>
servletEndpoints
)
{
Assert
.
notNull
(
servletEndpoints
,
"ServletEndpoints must not be null"
);
this
.
basePaths
.
addAll
(
basePaths
);
if
(
CollectionUtils
.
isEmpty
(
this
.
basePaths
))
{
this
.
basePaths
.
add
(
""
);
}
this
.
servletEndpoints
=
servletEndpoints
;
this
.
servletEndpoints
=
servletEndpoints
;
}
}
...
@@ -59,14 +73,20 @@ public class ServletEndpointRegistrar implements ServletContextInitializer {
...
@@ -59,14 +73,20 @@ public class ServletEndpointRegistrar implements ServletContextInitializer {
private
void
register
(
ServletContext
servletContext
,
private
void
register
(
ServletContext
servletContext
,
ExposableServletEndpoint
endpoint
)
{
ExposableServletEndpoint
endpoint
)
{
String
name
=
endpoint
.
getId
()
+
"-actuator-endpoint"
;
String
name
=
endpoint
.
getId
()
+
"-actuator-endpoint"
;
String
path
=
this
.
basePath
+
"/"
+
endpoint
.
getRootPath
();
String
urlMapping
=
(
path
.
endsWith
(
"/"
)
?
path
+
"*"
:
path
+
"/*"
);
EndpointServlet
endpointServlet
=
endpoint
.
getEndpointServlet
();
EndpointServlet
endpointServlet
=
endpoint
.
getEndpointServlet
();
Dynamic
registration
=
servletContext
.
addServlet
(
name
,
Dynamic
registration
=
servletContext
.
addServlet
(
name
,
endpointServlet
.
getServlet
());
endpointServlet
.
getServlet
());
registration
.
addMapping
(
urlMapping
);
registration
.
addMapping
(
getUrlMappings
(
endpoint
.
getRootPath
(),
name
)
);
registration
.
setInitParameters
(
endpointServlet
.
getInitParameters
());
registration
.
setInitParameters
(
endpointServlet
.
getInitParameters
());
logger
.
info
(
"Registered '"
+
path
+
"' to "
+
name
);
}
private
String
[]
getUrlMappings
(
String
endpointPath
,
String
name
)
{
return
this
.
basePaths
.
stream
()
.
map
((
bp
)
->
(
bp
!=
null
?
bp
+
"/"
+
endpointPath
:
"/"
+
endpointPath
))
.
distinct
().
map
((
p
)
->
{
logger
.
info
(
"Registered '"
+
p
+
"' to "
+
name
);
return
(
p
.
endsWith
(
"/"
)
?
p
+
"*"
:
p
+
"/*"
);
}).
toArray
(
String
[]::
new
);
}
}
}
}
spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/ServletEndpointRegistrarTests.java
View file @
fddc9e9c
...
@@ -18,6 +18,8 @@ package org.springframework.boot.actuate.endpoint.web;
...
@@ -18,6 +18,8 @@ package org.springframework.boot.actuate.endpoint.web;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.LinkedHashSet
;
import
java.util.Set
;
import
javax.servlet.GenericServlet
;
import
javax.servlet.GenericServlet
;
import
javax.servlet.Servlet
;
import
javax.servlet.Servlet
;
...
@@ -47,6 +49,7 @@ import static org.mockito.Mockito.verify;
...
@@ -47,6 +49,7 @@ import static org.mockito.Mockito.verify;
* Tests for {@link ServletEndpointRegistrar}.
* Tests for {@link ServletEndpointRegistrar}.
*
*
* @author Phillip Webb
* @author Phillip Webb
* @author Madhura Bhave
*/
*/
public
class
ServletEndpointRegistrarTests
{
public
class
ServletEndpointRegistrarTests
{
...
@@ -73,14 +76,14 @@ public class ServletEndpointRegistrarTests {
...
@@ -73,14 +76,14 @@ public class ServletEndpointRegistrarTests {
public
void
createWhenServletEndpointsIsNullShouldThrowException
()
{
public
void
createWhenServletEndpointsIsNullShouldThrowException
()
{
this
.
thrown
.
expect
(
IllegalArgumentException
.
class
);
this
.
thrown
.
expect
(
IllegalArgumentException
.
class
);
this
.
thrown
.
expectMessage
(
"ServletEndpoints must not be null"
);
this
.
thrown
.
expectMessage
(
"ServletEndpoints must not be null"
);
new
ServletEndpointRegistrar
(
null
,
null
);
new
ServletEndpointRegistrar
(
(
String
)
null
,
null
);
}
}
@Test
@Test
public
void
onStartupShouldRegisterServlets
()
throws
Exception
{
public
void
onStartupShouldRegisterServlets
()
throws
Exception
{
ExposableServletEndpoint
endpoint
=
mockEndpoint
(
ExposableServletEndpoint
endpoint
=
mockEndpoint
(
new
EndpointServlet
(
TestServlet
.
class
));
new
EndpointServlet
(
TestServlet
.
class
));
ServletEndpointRegistrar
registrar
=
new
ServletEndpointRegistrar
(
null
,
ServletEndpointRegistrar
registrar
=
new
ServletEndpointRegistrar
(
(
String
)
null
,
Collections
.
singleton
(
endpoint
));
Collections
.
singleton
(
endpoint
));
registrar
.
onStartup
(
this
.
servletContext
);
registrar
.
onStartup
(
this
.
servletContext
);
verify
(
this
.
servletContext
).
addServlet
(
eq
(
"test-actuator-endpoint"
),
verify
(
this
.
servletContext
).
addServlet
(
eq
(
"test-actuator-endpoint"
),
...
@@ -102,6 +105,64 @@ public class ServletEndpointRegistrarTests {
...
@@ -102,6 +105,64 @@ public class ServletEndpointRegistrarTests {
verify
(
this
.
dynamic
).
addMapping
(
"/actuator/test/*"
);
verify
(
this
.
dynamic
).
addMapping
(
"/actuator/test/*"
);
}
}
@Test
public
void
onStartupWhenHasMultipleBasePathsShouldIncludeAllBasePaths
()
throws
Exception
{
ExposableServletEndpoint
endpoint
=
mockEndpoint
(
new
EndpointServlet
(
TestServlet
.
class
));
Set
<
String
>
basePaths
=
new
LinkedHashSet
<>();
basePaths
.
add
(
"/actuator"
);
basePaths
.
add
(
"/admin"
);
basePaths
.
add
(
"/application"
);
ServletEndpointRegistrar
registrar
=
new
ServletEndpointRegistrar
(
basePaths
,
Collections
.
singleton
(
endpoint
));
registrar
.
onStartup
(
this
.
servletContext
);
verify
(
this
.
servletContext
).
addServlet
(
eq
(
"test-actuator-endpoint"
),
this
.
servlet
.
capture
());
assertThat
(
this
.
servlet
.
getValue
()).
isInstanceOf
(
TestServlet
.
class
);
ArgumentCaptor
<
String
>
captor
=
ArgumentCaptor
.
forClass
(
String
.
class
);
verify
(
this
.
dynamic
).
addMapping
(
captor
.
capture
());
assertThat
(
captor
.
getAllValues
()).
containsExactlyInAnyOrder
(
"/application/test/*"
,
"/admin/test/*"
,
"/actuator/test/*"
);
}
@Test
public
void
onStartupWhenHasEmptyBasePathsShouldIncludeRoot
()
throws
Exception
{
ExposableServletEndpoint
endpoint
=
mockEndpoint
(
new
EndpointServlet
(
TestServlet
.
class
));
Set
<
String
>
basePaths
=
Collections
.
emptySet
();
ServletEndpointRegistrar
registrar
=
new
ServletEndpointRegistrar
(
basePaths
,
Collections
.
singleton
(
endpoint
));
registrar
.
onStartup
(
this
.
servletContext
);
verify
(
this
.
dynamic
).
addMapping
(
"/test/*"
);
}
@Test
public
void
onStartupWhenHasBasePathsHasNullValueShouldIncludeRoot
()
throws
Exception
{
ExposableServletEndpoint
endpoint
=
mockEndpoint
(
new
EndpointServlet
(
TestServlet
.
class
));
Set
<
String
>
basePaths
=
new
LinkedHashSet
<>();
basePaths
.
add
(
null
);
ServletEndpointRegistrar
registrar
=
new
ServletEndpointRegistrar
(
basePaths
,
Collections
.
singleton
(
endpoint
));
registrar
.
onStartup
(
this
.
servletContext
);
verify
(
this
.
dynamic
).
addMapping
(
"/test/*"
);
}
@Test
public
void
onStartupWhenDuplicateValuesShouldIncludeDistinct
()
throws
Exception
{
ExposableServletEndpoint
endpoint
=
mockEndpoint
(
new
EndpointServlet
(
TestServlet
.
class
));
Set
<
String
>
basePaths
=
new
LinkedHashSet
<>();
basePaths
.
add
(
""
);
basePaths
.
add
(
null
);
ServletEndpointRegistrar
registrar
=
new
ServletEndpointRegistrar
(
basePaths
,
Collections
.
singleton
(
endpoint
));
registrar
.
onStartup
(
this
.
servletContext
);
verify
(
this
.
dynamic
).
addMapping
(
"/test/*"
);
}
@Test
@Test
public
void
onStartupWhenHasInitParametersShouldRegisterInitParameters
()
public
void
onStartupWhenHasInitParametersShouldRegisterInitParameters
()
throws
Exception
{
throws
Exception
{
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration.java
View file @
fddc9e9c
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
servlet
;
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
servlet
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.List
;
import
javax.servlet.MultipartConfigElement
;
import
javax.servlet.MultipartConfigElement
;
...
@@ -160,8 +161,9 @@ public class DispatcherServletAutoConfiguration {
...
@@ -160,8 +161,9 @@ public class DispatcherServletAutoConfiguration {
@ConditionalOnMissingBean
(
DispatcherServletPathProvider
.
class
)
@ConditionalOnMissingBean
(
DispatcherServletPathProvider
.
class
)
@ConditionalOnSingleCandidate
(
DispatcherServlet
.
class
)
@ConditionalOnSingleCandidate
(
DispatcherServlet
.
class
)
public
DispatcherServletPathProvider
dispatcherServletPathProvider
()
{
public
DispatcherServletPathProvider
dispatcherServletPathProvider
()
{
return
()
->
DispatcherServletRegistrationConfiguration
.
this
.
serverProperties
return
()
->
Collections
.
singleton
(
.
getServlet
().
getPath
();
DispatcherServletRegistrationConfiguration
.
this
.
serverProperties
.
getServlet
().
getPath
());
}
}
}
}
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletPathProvider.java
View file @
fddc9e9c
...
@@ -16,11 +16,13 @@
...
@@ -16,11 +16,13 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
servlet
;
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
servlet
;
import
java.util.Set
;
import
org.springframework.web.servlet.DispatcherServlet
;
import
org.springframework.web.servlet.DispatcherServlet
;
/**
/**
* Interface that provides the path
of
the {@link DispatcherServlet} in an application
* Interface that provides the path
s that
the {@link DispatcherServlet} in an application
* context.
* context
is mapped to
.
*
*
* @author Madhura Bhave
* @author Madhura Bhave
* @since 2.0.2
* @since 2.0.2
...
@@ -28,6 +30,6 @@ import org.springframework.web.servlet.DispatcherServlet;
...
@@ -28,6 +30,6 @@ import org.springframework.web.servlet.DispatcherServlet;
@FunctionalInterface
@FunctionalInterface
public
interface
DispatcherServletPathProvider
{
public
interface
DispatcherServletPathProvider
{
S
tring
getServletPath
();
S
et
<
String
>
getServletPaths
();
}
}
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfigurationTests.java
View file @
fddc9e9c
...
@@ -112,7 +112,7 @@ public class DispatcherServletAutoConfigurationTests {
...
@@ -112,7 +112,7 @@ public class DispatcherServletAutoConfigurationTests {
.
containsExactly
(
"/spring/*"
);
.
containsExactly
(
"/spring/*"
);
assertThat
(
registration
.
getMultipartConfig
()).
isNull
();
assertThat
(
registration
.
getMultipartConfig
()).
isNull
();
assertThat
(
context
.
getBean
(
DispatcherServletPathProvider
.
class
)
assertThat
(
context
.
getBean
(
DispatcherServletPathProvider
.
class
)
.
getServletPath
()).
isEqualTo
(
"/spring"
);
.
getServletPath
s
()).
containsExactly
(
"/spring"
);
});
});
}
}
...
@@ -129,8 +129,8 @@ public class DispatcherServletAutoConfigurationTests {
...
@@ -129,8 +129,8 @@ public class DispatcherServletAutoConfigurationTests {
this
.
contextRunner
.
withUserConfiguration
(
CustomDispatcherServletSameName
.
class
)
this
.
contextRunner
.
withUserConfiguration
(
CustomDispatcherServletSameName
.
class
)
.
withPropertyValues
(
"server.servlet.path:/spring"
)
.
withPropertyValues
(
"server.servlet.path:/spring"
)
.
run
((
context
)
->
assertThat
(
context
.
run
((
context
)
->
assertThat
(
context
.
getBean
(
DispatcherServletPathProvider
.
class
).
getServletPath
())
.
getBean
(
DispatcherServletPathProvider
.
class
).
getServletPath
s
())
.
isEqualTo
(
"/spring"
));
.
containsExactly
(
"/spring"
));
}
}
@Test
@Test
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment