Add additional ViewResolver configuration

The DispatcherServlet adds a default InternalViewResolver
which was used by some apps, but when the actuator was
available it added an "/error" bean and effectively
switched off the default view resolver. The net fix was
to add an InternalViewResolver at the same time as
adding any other ViewResolvers.

[Fixes #55357516] [bs-290] Actuator UI app cannot serve static index.html
pull/50/head
Dave Syer 11 years ago committed by Phillip Webb
parent 4c4e013c5e
commit d205d9404a

@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.thymeleaf.TemplateProcessingParameters; import org.thymeleaf.TemplateProcessingParameters;
@ -153,6 +154,9 @@ public class ThymeleafAutoConfiguration {
ThymeleafViewResolver resolver = new ThymeleafViewResolver(); ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(this.templateEngine); resolver.setTemplateEngine(this.templateEngine);
resolver.setCharacterEncoding("UTF-8"); resolver.setCharacterEncoding("UTF-8");
// Needs to come before any fallback resolver (e.g. a
// InternalResourceViewResolver)
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 20);
return resolver; return resolver;
} }

@ -58,6 +58,7 @@ import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.servlet.view.BeanNameViewResolver; import org.springframework.web.servlet.view.BeanNameViewResolver;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
/** /**
* {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}. * {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}.
@ -110,6 +111,14 @@ public class WebMvcAutoConfiguration {
@Autowired @Autowired
private ResourceLoader resourceLoader; private ResourceLoader resourceLoader;
@ConditionalOnBean(View.class)
@ConditionalOnMissingBean(InternalResourceViewResolver.class)
@Bean
public InternalResourceViewResolver defaultViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
return resolver;
}
@ConditionalOnBean(View.class) @ConditionalOnBean(View.class)
@Bean @Bean
public BeanNameViewResolver beanNameViewResolver() { public BeanNameViewResolver beanNameViewResolver() {
@ -124,6 +133,9 @@ public class WebMvcAutoConfiguration {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(beanFactory resolver.setContentNegotiationManager(beanFactory
.getBean(ContentNegotiationManager.class)); .getBean(ContentNegotiationManager.class));
// ContentNegotiatingViewResolver uses all the other view resolvers to locate
// a view so it should have a high precedence
resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
return resolver; return resolver;
} }

@ -25,7 +25,6 @@ import org.junit.After;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
@ -35,7 +34,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.View; import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.AbstractView; import org.springframework.web.servlet.view.AbstractView;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -78,15 +76,6 @@ public class WebMvcAutoConfigurationTests {
assertEquals(6, this.context.getBeanNamesForType(HandlerMapping.class).length); assertEquals(6, this.context.getBeanNamesForType(HandlerMapping.class).length);
} }
@Test
public void viewResolversCreatedIfViewsPresent() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(Config.class, ViewConfig.class,
WebMvcAutoConfiguration.class);
this.context.refresh();
assertEquals(2, this.context.getBeanNamesForType(ViewResolver.class).length);
}
@Configuration @Configuration
protected static class ViewConfig { protected static class ViewConfig {

@ -19,6 +19,11 @@
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId> <artifactId>spring-boot-starter-tomcat</artifactId>

Loading…
Cancel
Save