[bs-150] Add HTML error page to Actuator UI apps

The ErrorEndpoint now handles text/html requests differently, delegating
to a View named "error". This view will not exist by default so the user
will see an ugly 500 error, but it's easy to fix and there isn't a good
to provide a default.

[Fixes #51214943]
pull/2/merge
Dave Syer 12 years ago
parent 7ca2a18ab9
commit 6c5f9a5961

@ -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<String, Object> map = error(request);
return new ModelAndView("error", map);
}
@RequestMapping(value = "${endpoints.error.path:/error}")
@ResponseBody
public Map<String, Object> error(HttpServletRequest request) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("timestamp", new Date());
try {
Throwable error = (Throwable) request
.getAttribute("javax.servlet.error.exception");
@ -88,4 +97,5 @@ public class ErrorEndpoint {
return map;
}
}
}

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Error</title>
<link rel="stylesheet" th:href="@{/resources/css/bootstrap.min.css}"
href="../../resources/css/bootstrap.min.css" />
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="http://www.thymeleaf.org"> Thymeleaf -
Plain </a>
<ul class="nav">
<li><a th:href="@{/}" href="home.html"> Home </a></li>
</ul>
</div>
</div>
<h1 th:text="${title}">Title</h1>
<div id="created" th:text="${#dates.format(timestamp)}">July 11,
2012 2:17:16 PM CDT</div>
<div>
There was an unexpected error (type=<span th:text="${error}">Bad</span>, status=<span th:text="${status}">500</span>).
</div>
<div th:text="${message}">Fake content</div>
<div>
Please contact the operator with the above information.
</div>
</div>
</body>
</html>

@ -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<String> entity = getRestTemplate().getForEntity(
"http://localhost:8080", String.class);
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
ResponseEntity<String> entity = getRestTemplate().exchange(
"http://localhost:8080", HttpMethod.GET, new HttpEntity<Void>(headers),
String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
assertTrue("Wrong body (title doesn't match):\n" + entity.getBody(), entity
.getBody().contains("<title>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() {

Loading…
Cancel
Save