diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java index 1482d0220a7..94e0bff791f 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -196,8 +196,12 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration { } private boolean isActuatorEndpointPath(String path) { - return this.halJsonMvcEndpoint != null && (this.management.getContextPath() - + this.halJsonMvcEndpoint.getPath()).equals(path); + if (this.halJsonMvcEndpoint != null) { + String toMatch = this.management.getContextPath() + + this.halJsonMvcEndpoint.getPath(); + return toMatch.equals(path) || (toMatch + "/").equals(path); + } + return false; } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java index cb165235803..c0c32516adc 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalJsonMvcEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,11 +87,6 @@ public class HalJsonMvcEndpoint extends WebMvcConfigurerAdapter return new ResourceSupport(); } - @RequestMapping(path = "/", produces = MediaType.APPLICATION_JSON_VALUE) - public String forward() { - return "redirect:" + this.managementServletContext.getContextPath() + this.path; - } - public void setPath(String path) { this.path = path; } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java index 0afafcb4480..9b65cdd077c 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,6 @@ import org.springframework.web.context.WebApplicationContext; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -77,10 +76,9 @@ public class HalBrowserMvcEndpointManagementContextPathIntegrationTests { } @Test - public void redirectJson() throws Exception { + public void actuatorHomeWithTrailingSlashJson() throws Exception { this.mockMvc.perform(get("/admin/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isFound()) - .andExpect(header().string("location", "/admin")); + .andExpect(status().isOk()).andExpect(jsonPath("$._links").exists()); } @Test diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java index 8ad3a60c7d3..855dc417572 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -97,6 +97,18 @@ public class HalBrowserMvcEndpointServerContextPathIntegrationTests { entity.getBody().contains("\"_links\":")); } + @Test + public void actuatorLinksWithTrailingSlash() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + ResponseEntity entity = new TestRestTemplate().exchange( + "http://localhost:" + this.port + "/spring/actuator/", HttpMethod.GET, + new HttpEntity(null, headers), String.class); + assertEquals(HttpStatus.OK, entity.getStatusCode()); + assertTrue("Wrong body: " + entity.getBody(), + entity.getBody().contains("\"_links\":")); + } + @MinimalActuatorHypermediaApplication @RestController public static class SpringBootHypermediaApplication { diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerPortIntegrationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerPortIntegrationTests.java index 495cfc21927..6f9ca98e3a2 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerPortIntegrationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerPortIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,6 +75,20 @@ public class HalBrowserMvcEndpointServerPortIntegrationTests { entity.getBody().contains(":" + this.port)); } + @Test + public void linksWithTrailingSlash() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + ResponseEntity entity = new TestRestTemplate().exchange( + "http://localhost:" + this.port + "/actuator/", HttpMethod.GET, + new HttpEntity(null, headers), String.class); + assertEquals(HttpStatus.OK, entity.getStatusCode()); + assertTrue("Wrong body: " + entity.getBody(), + entity.getBody().contains("\"_links\":")); + assertTrue("Wrong body: " + entity.getBody(), + entity.getBody().contains(":" + this.port)); + } + @Test public void browser() throws Exception { HttpHeaders headers = new HttpHeaders(); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointVanillaIntegrationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointVanillaIntegrationTests.java index f9f0c9c4a5b..681f959b2f4 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointVanillaIntegrationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointVanillaIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,6 +78,13 @@ public class HalBrowserMvcEndpointVanillaIntegrationTests { .andExpect(header().doesNotExist("cache-control")); } + @Test + public void linksWithTrailingSlash() throws Exception { + this.mockMvc.perform(get("/actuator/").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andExpect(jsonPath("$._links").exists()) + .andExpect(header().doesNotExist("cache-control")); + } + @Test public void browser() throws Exception { MvcResult response = this.mockMvc