diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMapping.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMapping.java index 85cf62b96e6..8f1635ae401 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMapping.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/EndpointHandlerMapping.java @@ -84,6 +84,7 @@ public class EndpointHandlerMapping extends RequestMappingHandlerMapping { // By default the static resource handler mapping is LOWEST_PRECEDENCE - 1 // and the RequestMappingHandlerMapping is 0 (we ideally want to be before both) setOrder(-100); + setUseSuffixPatternMatch(false); } @Override @@ -121,7 +122,7 @@ public class EndpointHandlerMapping extends RequestMappingHandlerMapping { String prefix = StringUtils.hasText(this.prefix) ? this.prefix + path : path; Set defaultPatterns = mapping.getPatternsCondition().getPatterns(); if (defaultPatterns.isEmpty()) { - return new String[] { prefix }; + return new String[] { prefix, prefix + ".json" }; } List patterns = new ArrayList(defaultPatterns); for (int i = 0; i < patterns.size(); i++) { @@ -142,7 +143,8 @@ public class EndpointHandlerMapping extends RequestMappingHandlerMapping { private RequestMappingInfo withNewPatterns(RequestMappingInfo mapping, String[] patternStrings) { - PatternsRequestCondition patterns = new PatternsRequestCondition(patternStrings); + PatternsRequestCondition patterns = new PatternsRequestCondition(patternStrings, + null, null, useSuffixPatternMatch(), useTrailingSlashMatch(), null); return new RequestMappingInfo(patterns, mapping.getMethodsCondition(), mapping.getParamsCondition(), mapping.getHeadersCondition(), mapping.getConsumesCondition(), mapping.getProducesCondition(), diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpointIntegrationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpointIntegrationTests.java index 5fdf6ba1d46..fe69c09b3af 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpointIntegrationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/MvcEndpointIntegrationTests.java @@ -90,6 +90,22 @@ public class MvcEndpointIntegrationTests { assertIndentedJsonResponse(SpringDataRestConfiguration.class); } + @Test + public void fileExtensionNotFound() throws Exception { + this.context = new AnnotationConfigWebApplicationContext(); + this.context.register(DefaultConfiguration.class); + MockMvc mockMvc = createMockMvc(); + mockMvc.perform(get("/beans.cmd")).andExpect(status().isNotFound()); + } + + @Test + public void jsonExtensionProvided() throws Exception { + this.context = new AnnotationConfigWebApplicationContext(); + this.context.register(DefaultConfiguration.class); + MockMvc mockMvc = createMockMvc(); + mockMvc.perform(get("/beans.json")).andExpect(status().isOk()); + } + @Test public void nonSensitiveEndpointsAreNotSecureByDefault() throws Exception { this.context = new AnnotationConfigWebApplicationContext();