diff --git a/spring-bootstrap-actuator/src/main/java/org/springframework/bootstrap/actuate/endpoint/error/ErrorEndpoint.java b/spring-bootstrap-actuator/src/main/java/org/springframework/bootstrap/actuate/endpoint/error/ErrorEndpoint.java index 57cbfeac92..45efcbdba8 100644 --- a/spring-bootstrap-actuator/src/main/java/org/springframework/bootstrap/actuate/endpoint/error/ErrorEndpoint.java +++ b/spring-bootstrap-actuator/src/main/java/org/springframework/bootstrap/actuate/endpoint/error/ErrorEndpoint.java @@ -18,6 +18,7 @@ package org.springframework.bootstrap.actuate.endpoint.error; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; @@ -31,6 +32,7 @@ import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; /** * Basic fallback global error endpoint, rendering servlet container error codes and @@ -46,10 +48,17 @@ public class ErrorEndpoint { private Log logger = LogFactory.getLog(ErrorEndpoint.class); - @RequestMapping("${endpoints.error.path:/error}") + @RequestMapping(value = "${endpoints.error.path:/error}", produces = "text/html") + public ModelAndView errorHtml(HttpServletRequest request) { + Map map = error(request); + return new ModelAndView("error", map); + } + + @RequestMapping(value = "${endpoints.error.path:/error}") @ResponseBody public Map error(HttpServletRequest request) { Map map = new LinkedHashMap(); + map.put("timestamp", new Date()); try { Throwable error = (Throwable) request .getAttribute("javax.servlet.error.exception"); @@ -88,4 +97,5 @@ public class ErrorEndpoint { return map; } } + } diff --git a/spring-bootstrap-samples/spring-bootstrap-actuator-ui-sample/src/main/resources/templates/error.html b/spring-bootstrap-samples/spring-bootstrap-actuator-ui-sample/src/main/resources/templates/error.html new file mode 100644 index 0000000000..9cba172064 --- /dev/null +++ b/spring-bootstrap-samples/spring-bootstrap-actuator-ui-sample/src/main/resources/templates/error.html @@ -0,0 +1,31 @@ + + + +Error + + + +
+ +

Title

+
July 11, + 2012 2:17:16 PM CDT
+
+ There was an unexpected error (type=Bad, status=500). +
+
Fake content
+
+ Please contact the operator with the above information. +
+
+ + \ No newline at end of file diff --git a/spring-bootstrap-samples/spring-bootstrap-actuator-ui-sample/src/test/java/org/springframework/bootstrap/sample/ui/ActuatorUiBootstrapApplicationTests.java b/spring-bootstrap-samples/spring-bootstrap-actuator-ui-sample/src/test/java/org/springframework/bootstrap/sample/ui/ActuatorUiBootstrapApplicationTests.java index a909f3f4c0..d97561a60f 100644 --- a/spring-bootstrap-samples/spring-bootstrap-actuator-ui-sample/src/test/java/org/springframework/bootstrap/sample/ui/ActuatorUiBootstrapApplicationTests.java +++ b/spring-bootstrap-samples/spring-bootstrap-actuator-ui-sample/src/test/java/org/springframework/bootstrap/sample/ui/ActuatorUiBootstrapApplicationTests.java @@ -1,6 +1,7 @@ package org.springframework.bootstrap.sample.ui; import java.io.IOException; +import java.util.Arrays; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Executors; @@ -12,7 +13,11 @@ import org.junit.BeforeClass; import org.junit.Test; import org.springframework.bootstrap.SpringApplication; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpResponse; import org.springframework.web.client.DefaultResponseErrorHandler; @@ -54,8 +59,11 @@ public class ActuatorUiBootstrapApplicationTests { @Test public void testHome() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( - "http://localhost:8080", String.class); + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); + ResponseEntity entity = getRestTemplate().exchange( + "http://localhost:8080", HttpMethod.GET, new HttpEntity(headers), + String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertTrue("Wrong body (title doesn't match):\n" + entity.getBody(), entity .getBody().contains("Hello")); @@ -77,6 +85,20 @@ public class ActuatorUiBootstrapApplicationTests { assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); } + @Test + public void testError() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); + ResponseEntity<String> entity = getRestTemplate().exchange( + "http://localhost:8080/error", HttpMethod.GET, + new HttpEntity<Void>(headers), String.class); + assertEquals(HttpStatus.OK, entity.getStatusCode()); + assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody() + .contains("<html>")); + assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody() + .contains("<body>")); + } + private RestTemplate getRestTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {