diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ErrorMvcAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ErrorMvcAutoConfiguration.java
index 4b3185a6c2..cef6bb7bbe 100644
--- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ErrorMvcAutoConfiguration.java
+++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ErrorMvcAutoConfiguration.java
@@ -42,6 +42,7 @@ import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.expression.Expression;
@@ -52,6 +53,7 @@ import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.View;
+import org.springframework.web.servlet.view.BeanNameViewResolver;
/**
* {@link EnableAutoConfiguration Auto-configuration} to render errors via a MVC error
@@ -80,19 +82,34 @@ public class ErrorMvcAutoConfiguration implements EmbeddedServletContainerCustom
factory.addErrorPages(new ErrorPage(this.errorPath));
}
- private SpelView defaultErrorView = new SpelView(
- "
Whitelabel Error Page
"
- + "This application has no explicit mapping for /error, so you are seeing this as a fallback.
"
- + "${timestamp}
"
- + "There was an unexpected error (type=${error}, status=${status}).
"
- + "${message}
" + "");
-
- @Bean(name = "error")
- @ConditionalOnMissingBean(name = "error")
+ @Configuration
@ConditionalOnExpression("${error.whitelabel.enabled:true}")
@Conditional(ErrorTemplateMissingCondition.class)
- public View defaultErrorView() {
- return this.defaultErrorView;
+ protected static class WhitelabelErrorViewConfiguration {
+
+ private SpelView defaultErrorView = new SpelView(
+ "Whitelabel Error Page
"
+ + "This application has no explicit mapping for /error, so you are seeing this as a fallback.
"
+ + "${timestamp}
"
+ + "There was an unexpected error (type=${error}, status=${status}).
"
+ + "${message}
" + "");
+
+ @Bean(name = "error")
+ @ConditionalOnMissingBean(name = "error")
+ public View defaultErrorView() {
+ return this.defaultErrorView;
+ }
+
+ // If the user adds @EnableWebMvc then the bean name view resolver from
+ // WebMvcAutoConfiguration disappears, so add it back in to avoid disappointment.
+ @Bean
+ @ConditionalOnMissingBean(BeanNameViewResolver.class)
+ public BeanNameViewResolver beanNameViewResolver() {
+ BeanNameViewResolver resolver = new BeanNameViewResolver();
+ resolver.setOrder(0);
+ return resolver;
+ }
+
}
private static class ErrorTemplateMissingCondition extends SpringBootCondition {
diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java
index 7d989bb29a..5f014eb5d8 100644
--- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java
+++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointAutoConfigurationTests.java
@@ -16,6 +16,8 @@
package org.springframework.boot.actuate.autoconfigure;
+import java.util.Map;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -30,11 +32,13 @@ import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigurationReport;
+import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
/**
* Tests for {@link EndpointAutoConfiguration}.
@@ -73,6 +77,21 @@ public class EndpointAutoConfigurationTests {
assertNotNull(this.context.getBean(TraceEndpoint.class));
}
+ @Test
+ public void healthEndpoint() {
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.register(EndpointAutoConfiguration.class,
+ EmbeddedDataSourceConfiguration.class);
+ this.context.refresh();
+ HealthEndpoint> bean = this.context.getBean(HealthEndpoint.class);
+ assertNotNull(bean);
+ @SuppressWarnings("unchecked")
+ Map result = (Map) bean.invoke();
+ assertNotNull(result);
+ assertTrue("Wrong result: " + result, result.containsKey("status"));
+ assertTrue("Wrong result: " + result, result.containsKey("database"));
+ }
+
@Test
public void autoconfigurationAuditEndpoints() {
this.context = new AnnotationConfigApplicationContext();
diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/BasicErrorControllerSpecialIntegrationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/BasicErrorControllerSpecialIntegrationTests.java
new file mode 100644
index 0000000000..dcdbfa5369
--- /dev/null
+++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/BasicErrorControllerSpecialIntegrationTests.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.actuate.web;
+
+import org.junit.After;
+import org.junit.Test;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.ConfigurableWebApplicationContext;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+import static org.junit.Assert.assertTrue;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+/**
+ * @author Dave Syer
+ */
+public class BasicErrorControllerSpecialIntegrationTests {
+
+ private ConfigurableWebApplicationContext wac;
+
+ private MockMvc mockMvc;
+
+ @After
+ public void close() {
+ if (this.wac != null) {
+ this.wac.close();
+ }
+ }
+
+ public void setup(ConfigurableWebApplicationContext context) {
+ this.wac = context;
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
+ }
+
+ @Test
+ public void errorPageAvailableWithParentContext() throws Exception {
+ setup((ConfigurableWebApplicationContext) new SpringApplicationBuilder(
+ ParentConfiguration.class).child(ChildConfiguration.class).run());
+ MvcResult response = this.mockMvc
+ .perform(get("/error").accept(MediaType.TEXT_HTML))
+ .andExpect(status().isOk()).andReturn();
+ String content = response.getResponse().getContentAsString();
+ assertTrue("Wrong content: " + content, content.contains("status=999"));
+ }
+
+ @Test
+ public void errorPageAvailableWithMvcIncluded() throws Exception {
+ setup((ConfigurableWebApplicationContext) SpringApplication
+ .run(WebMvcIncludedConfiguration.class));
+ MvcResult response = this.mockMvc
+ .perform(get("/error").accept(MediaType.TEXT_HTML))
+ .andExpect(status().isOk()).andReturn();
+ String content = response.getResponse().getContentAsString();
+ assertTrue("Wrong content: " + content, content.contains("status=999"));
+ }
+
+ @Configuration
+ // TODO: fix this so it doesn't need to be excluded
+ @EnableAutoConfiguration(exclude = ServerPropertiesAutoConfiguration.class)
+ protected static class ParentConfiguration {
+
+ }
+
+ @Configuration
+ @EnableAutoConfiguration
+ @EnableWebMvc
+ protected static class WebMvcIncludedConfiguration {
+ // For manual testing
+ public static void main(String[] args) {
+ SpringApplication.run(WebMvcIncludedConfiguration.class, args);
+ }
+
+ }
+
+ @Configuration
+ @EnableAutoConfiguration
+ protected static class ChildConfiguration {
+
+ // For manual testing
+ public static void main(String[] args) {
+ new SpringApplicationBuilder(ParentConfiguration.class).child(
+ ChildConfiguration.class).run(args);
+ }
+ }
+
+}