Merge branch '2.0.x'

This commit is contained in:
Phillip Webb
2018-07-26 13:23:07 +01:00
23 changed files with 463 additions and 279 deletions

View File

@@ -27,7 +27,7 @@ import java.util.stream.Stream;
import javax.servlet.http.HttpServletRequest;
import org.springframework.boot.autoconfigure.security.StaticResourceLocation;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
@@ -96,14 +96,14 @@ public final class StaticResourceRequest {
* Locations}.
*/
public static final class StaticResourceRequestMatcher
extends ApplicationContextRequestMatcher<WebMvcProperties> {
extends ApplicationContextRequestMatcher<DispatcherServletPath> {
private final Set<StaticResourceLocation> locations;
private volatile RequestMatcher delegate;
private StaticResourceRequestMatcher(Set<StaticResourceLocation> locations) {
super(WebMvcProperties.class);
super(DispatcherServletPath.class);
this.locations = locations;
}
@@ -134,25 +134,26 @@ public final class StaticResourceRequest {
}
@Override
protected void initialized(Supplier<WebMvcProperties> serverProperties) {
protected void initialized(
Supplier<DispatcherServletPath> dispatcherServletPath) {
this.delegate = new OrRequestMatcher(
getDelegateMatchers(serverProperties.get()));
getDelegateMatchers(dispatcherServletPath.get()));
}
private List<RequestMatcher> getDelegateMatchers(
WebMvcProperties serverProperties) {
return getPatterns(serverProperties).map(AntPathRequestMatcher::new)
DispatcherServletPath dispatcherServletPath) {
return getPatterns(dispatcherServletPath).map(AntPathRequestMatcher::new)
.collect(Collectors.toList());
}
private Stream<String> getPatterns(WebMvcProperties serverProperties) {
private Stream<String> getPatterns(DispatcherServletPath dispatcherServletPath) {
return this.locations.stream().flatMap(StaticResourceLocation::getPatterns)
.map(serverProperties.getServlet()::getPath);
.map(dispatcherServletPath::getRelativePath);
}
@Override
protected boolean matches(HttpServletRequest request,
Supplier<WebMvcProperties> context) {
Supplier<DispatcherServletPath> context) {
return this.delegate.matches(request);
}

View File

@@ -17,7 +17,6 @@
package org.springframework.boot.autoconfigure.web.servlet;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.servlet.MultipartConfigElement;
@@ -34,7 +33,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
@@ -134,11 +132,10 @@ public class DispatcherServletAutoConfiguration {
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public ServletRegistrationBean<DispatcherServlet> dispatcherServletRegistration(
public DispatcherServletRegistrationBean dispatcherServletRegistration(
DispatcherServlet dispatcherServlet) {
ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean<>(
dispatcherServlet,
this.webMvcProperties.getServlet().getServletMapping());
DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(
dispatcherServlet, this.webMvcProperties.getServlet().getPath());
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(
this.webMvcProperties.getServlet().getLoadOnStartup());
@@ -148,15 +145,6 @@ public class DispatcherServletAutoConfiguration {
return registration;
}
@Bean
@ConditionalOnMissingBean(DispatcherServletPathProvider.class)
@ConditionalOnSingleCandidate(DispatcherServlet.class)
public DispatcherServletPathProvider dispatcherServletPathProvider() {
return () -> Collections.singleton(
DispatcherServletRegistrationConfiguration.this.webMvcProperties
.getServlet().getPath());
}
}
@Order(Ordered.LOWEST_PRECEDENCE - 10)

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2012-2018 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.autoconfigure.web.servlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.web.servlet.DispatcherServlet;
/**
* Interface that can be used by auto-configurations that need path details for the
* {@link DispatcherServletAutoConfiguration#DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME
* default} {@link DispatcherServlet}.
*
* @author Madhura Bhave
* @author Stephane Nicoll
* @since 2.0.4
*/
@FunctionalInterface
public interface DispatcherServletPath {
/**
* Returns the configured path of the dispatcher servlet.
* @return the configured path
*/
String getPath();
/**
* Return a form of the given path that's relative to the dispatcher servlet path.
* @param path the path to make relative
* @return the relative path
*/
default String getRelativePath(String path) {
String prefix = getPrefix();
if (!path.startsWith("/")) {
path = "/" + path;
}
return prefix + path;
}
/**
* Return a cleaned up version of the path that can be used as a prefix for URLs. The
* resulting path will have path will not have a trailing slash.
* @return the prefix
* @see #getRelativePath(String)
*/
default String getPrefix() {
String result = getPath();
int index = result.indexOf('*');
if (index != -1) {
result = result.substring(0, index);
}
if (result.endsWith("/")) {
result = result.substring(0, result.length() - 1);
}
return result;
}
/**
* Return a URL mapping pattern that can be used with a
* {@link ServletRegistrationBean} to map the dispatcher servlet.
* @return the path as a servlet URL mapping
*/
default String getServletUrlMapping() {
if (getPath().equals("") || getPath().equals("/")) {
return "/";
}
if (getPath().contains("*")) {
return getPath();
}
if (getPath().endsWith("/")) {
return getPath() + "*";
}
return getPath() + "/*";
}
}

View File

@@ -16,8 +16,6 @@
package org.springframework.boot.autoconfigure.web.servlet;
import java.util.Set;
import org.springframework.web.servlet.DispatcherServlet;
/**
@@ -26,10 +24,13 @@ import org.springframework.web.servlet.DispatcherServlet;
*
* @author Madhura Bhave
* @since 2.0.2
* @deprecated since 2.0.4 in favor of {@link DispatcherServletPath} and
* {@link DispatcherServletRegistrationBean}
*/
@Deprecated
@FunctionalInterface
public interface DispatcherServletPathProvider {
Set<String> getServletPaths();
String getServletPath();
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2012-2018 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.autoconfigure.web.servlet;
import java.util.Collection;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.util.Assert;
import org.springframework.web.servlet.DispatcherServlet;
/**
* {@link ServletRegistrationBean} for the auto-configured {@link DispatcherServlet}. Both
* registeres the servlet and exposes {@link DispatcherServletPath} information.
*
* @author Phillip Webb
* @since 2.0.4
*/
public class DispatcherServletRegistrationBean extends
ServletRegistrationBean<DispatcherServlet> implements DispatcherServletPath {
private final String path;
/**
* Create a new {@link DispatcherServletRegistrationBean} instance for the given
* servlet and path.
* @param servlet the dispatcher servlet
* @param path the dispatcher servlet path
*/
public DispatcherServletRegistrationBean(DispatcherServlet servlet, String path) {
super(servlet);
Assert.notNull(path, "Path must not be null");
this.path = path;
super.addUrlMappings(getServletUrlMapping());
}
@Override
public String getPath() {
return this.path;
}
@Override
public void setUrlMappings(Collection<String> urlMappings) {
throw new UnsupportedOperationException(
"URL Mapping cannot be changed on a DispatcherServlet registration");
}
@Override
public void addUrlMappings(String... urlMappings) {
throw new UnsupportedOperationException(
"URL Mapping cannot be changed on a DispatcherServlet registration");
}
}

View File

@@ -49,6 +49,7 @@ import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvi
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -96,15 +97,15 @@ public class ErrorMvcAutoConfiguration {
private final ServerProperties serverProperties;
private final WebMvcProperties webMvcProperties;
private final DispatcherServletPath dispatcherServletPath;
private final List<ErrorViewResolver> errorViewResolvers;
public ErrorMvcAutoConfiguration(ServerProperties serverProperties,
WebMvcProperties webMvcProperties,
DispatcherServletPath dispatcherServletPath,
ObjectProvider<List<ErrorViewResolver>> errorViewResolversProvider) {
this.serverProperties = serverProperties;
this.webMvcProperties = webMvcProperties;
this.dispatcherServletPath = dispatcherServletPath;
this.errorViewResolvers = errorViewResolversProvider.getIfAvailable();
}
@@ -124,7 +125,7 @@ public class ErrorMvcAutoConfiguration {
@Bean
public ErrorPageCustomizer errorPageCustomizer() {
return new ErrorPageCustomizer(this.serverProperties, this.webMvcProperties);
return new ErrorPageCustomizer(this.serverProperties, this.dispatcherServletPath);
}
@Bean
@@ -331,21 +332,20 @@ public class ErrorMvcAutoConfiguration {
*/
private static class ErrorPageCustomizer implements ErrorPageRegistrar, Ordered {
private final ServerProperties serverProperties;
private final ServerProperties properties;
private final WebMvcProperties webMvcProperties;
private final DispatcherServletPath dispatcherServletPath;
protected ErrorPageCustomizer(ServerProperties serverProperties,
WebMvcProperties webMvcProperties) {
this.serverProperties = serverProperties;
this.webMvcProperties = webMvcProperties;
protected ErrorPageCustomizer(ServerProperties properties,
DispatcherServletPath dispatcherServletPath) {
this.properties = properties;
this.dispatcherServletPath = dispatcherServletPath;
}
@Override
public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
ErrorPage errorPage = new ErrorPage(
this.webMvcProperties.getServlet().getServletPrefix()
+ this.serverProperties.getError().getPath());
ErrorPage errorPage = new ErrorPage(this.dispatcherServletPath
.getRelativePath(this.properties.getError().getPath()));
errorPageRegistry.addErrorPages(errorPage);
}

View File

@@ -24,7 +24,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.autoconfigure.security.StaticResourceLocation;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockServletContext;
import org.springframework.security.web.util.matcher.RequestMatcher;
@@ -74,11 +74,9 @@ public class StaticResourceRequestTests {
@Test
public void atLocationWhenHasServletPathShouldMatchLocation() {
WebMvcProperties webMvcProperties = new WebMvcProperties();
webMvcProperties.getServlet().setPath("/foo");
RequestMatcher matcher = this.resourceRequest.at(StaticResourceLocation.CSS);
assertMatcher(matcher, webMvcProperties).matches("/foo", "/css/file.css");
assertMatcher(matcher, webMvcProperties).doesNotMatch("/foo", "/js/file.js");
assertMatcher(matcher, "/foo").matches("/foo", "/css/file.css");
assertMatcher(matcher, "/foo").doesNotMatch("/foo", "/js/file.js");
}
@Test
@@ -96,15 +94,16 @@ public class StaticResourceRequestTests {
}
private RequestMatcherAssert assertMatcher(RequestMatcher matcher) {
DispatcherServletPath dispatcherServletPath = () -> "";
StaticWebApplicationContext context = new StaticWebApplicationContext();
context.registerBean(WebMvcProperties.class);
context.registerBean(DispatcherServletPath.class, () -> dispatcherServletPath);
return assertThat(new RequestMatcherAssert(context, matcher));
}
private RequestMatcherAssert assertMatcher(RequestMatcher matcher,
WebMvcProperties webMvcProperties) {
private RequestMatcherAssert assertMatcher(RequestMatcher matcher, String path) {
DispatcherServletPath dispatcherServletPath = () -> path;
StaticWebApplicationContext context = new StaticWebApplicationContext();
context.registerBean(WebMvcProperties.class, () -> webMvcProperties);
context.registerBean(DispatcherServletPath.class, () -> dispatcherServletPath);
return assertThat(new RequestMatcherAssert(context, matcher));
}

View File

@@ -66,8 +66,7 @@ public class DispatcherServletAutoConfigurationTests {
.run((context) -> {
assertThat(context).doesNotHaveBean(ServletRegistrationBean.class);
assertThat(context).doesNotHaveBean(DispatcherServlet.class);
assertThat(context)
.doesNotHaveBean(DispatcherServletPathProvider.class);
assertThat(context).doesNotHaveBean(DispatcherServletPath.class);
});
}
@@ -77,7 +76,7 @@ public class DispatcherServletAutoConfigurationTests {
public void registrationOverrideWithDispatcherServletWrongName() {
this.contextRunner
.withUserConfiguration(CustomDispatcherServletDifferentName.class,
CustomDispatcherServletPathProvider.class)
CustomDispatcherServletPath.class)
.run((context) -> {
ServletRegistrationBean<?> registration = context
.getBean(ServletRegistrationBean.class);
@@ -91,7 +90,7 @@ public class DispatcherServletAutoConfigurationTests {
@Test
public void registrationOverrideWithAutowiredServlet() {
this.contextRunner.withUserConfiguration(CustomAutowiredRegistration.class,
CustomDispatcherServletPathProvider.class).run((context) -> {
CustomDispatcherServletPath.class).run((context) -> {
ServletRegistrationBean<?> registration = context
.getBean(ServletRegistrationBean.class);
assertThat(registration.getUrlMappings()).containsExactly("/foo");
@@ -111,43 +110,35 @@ public class DispatcherServletAutoConfigurationTests {
assertThat(registration.getUrlMappings())
.containsExactly("/spring/*");
assertThat(registration.getMultipartConfig()).isNull();
assertThat(context.getBean(DispatcherServletPathProvider.class)
.getServletPaths()).containsExactly("/spring");
assertThat(context.getBean(DispatcherServletPath.class).getPath())
.isEqualTo("/spring");
});
}
@Test
public void pathProviderNotCreatedWhenMultipleDispatcherServletsPresent() {
this.contextRunner
.withUserConfiguration(CustomDispatcherServletDifferentName.class)
.run((context) -> assertThat(context)
.doesNotHaveBean(DispatcherServletPathProvider.class));
}
@Test
public void pathProviderWhenCustomDispatcherServletSameNameShouldReturnConfiguredServletPath() {
public void dispatcherServletPathWhenCustomDispatcherServletSameNameShouldReturnConfiguredServletPath() {
this.contextRunner.withUserConfiguration(CustomDispatcherServletSameName.class)
.withPropertyValues("spring.mvc.servlet.path:/spring")
.run((context) -> assertThat(context
.getBean(DispatcherServletPathProvider.class).getServletPaths())
.containsExactly("/spring"));
.run((context) -> assertThat(
context.getBean(DispatcherServletPath.class).getPath())
.isEqualTo("/spring"));
}
@Test
public void pathProviderNotCreatedWhenDefaultDispatcherServletNotAvailable() {
public void dispatcherServletPathNotCreatedWhenDefaultDispatcherServletNotAvailable() {
this.contextRunner
.withUserConfiguration(CustomDispatcherServletDifferentName.class,
NonServletConfiguration.class)
.run((context) -> assertThat(context)
.doesNotHaveBean(DispatcherServletPathProvider.class));
.doesNotHaveBean(DispatcherServletPath.class));
}
@Test
public void pathProviderNotCreatedWhenCustomRegistrationBeanPresent() {
public void dispatcherServletPathNotCreatedWhenCustomRegistrationBeanPresent() {
this.contextRunner
.withUserConfiguration(CustomDispatcherServletRegistration.class)
.run((context) -> assertThat(context)
.doesNotHaveBean(DispatcherServletPathProvider.class));
.doesNotHaveBean(DispatcherServletPath.class));
}
@Test
@@ -237,11 +228,11 @@ public class DispatcherServletAutoConfigurationTests {
}
@Configuration
protected static class CustomDispatcherServletPathProvider {
protected static class CustomDispatcherServletPath {
@Bean
public DispatcherServletPathProvider dispatcherServletPathProvider() {
return mock(DispatcherServletPathProvider.class);
public DispatcherServletPath dispatcherServletPath() {
return mock(DispatcherServletPath.class);
}
}
@@ -259,8 +250,8 @@ public class DispatcherServletAutoConfigurationTests {
}
@Bean
public DispatcherServletPathProvider dispatcherServletPathProvider() {
return mock(DispatcherServletPathProvider.class);
public DispatcherServletPath dispatcherServletPath() {
return mock(DispatcherServletPath.class);
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2012-2018 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.autoconfigure.web.servlet;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DispatcherServletPath}.
*
* @author Phillip Webb
*/
public class DispatcherServletPathTests {
@Test
public void getRelativePathReturnsRelativePath() {
assertThat(((DispatcherServletPath) () -> "spring").getRelativePath("boot"))
.isEqualTo("spring/boot");
assertThat(((DispatcherServletPath) () -> "spring/").getRelativePath("boot"))
.isEqualTo("spring/boot");
assertThat(((DispatcherServletPath) () -> "spring").getRelativePath("/boot"))
.isEqualTo("spring/boot");
}
@Test
public void getPrefixWhenHasSimplePathReturnPath() {
assertThat(((DispatcherServletPath) () -> "spring").getPrefix())
.isEqualTo("spring");
}
@Test
public void getPrefixWhenHasPatternRemovesPattern() {
assertThat(((DispatcherServletPath) () -> "spring/*.do").getPrefix())
.isEqualTo("spring");
}
@Test
public void getPathWhenPathEndsWithSlashRemovesSlash() {
assertThat(((DispatcherServletPath) () -> "spring/").getPrefix())
.isEqualTo("spring");
}
@Test
public void getServletUrlMappingWhenPathIsEmptyReturnsSlash() {
assertThat(((DispatcherServletPath) () -> "").getServletUrlMapping())
.isEqualTo("/");
}
@Test
public void getServletUrlMappingWhenPathIsSlashReturnsSlash() {
assertThat(((DispatcherServletPath) () -> "/").getServletUrlMapping())
.isEqualTo("/");
}
@Test
public void getServletUrlMappingWhenPathContainsStarReturnsPath() {
assertThat(((DispatcherServletPath) () -> "spring/*.do").getServletUrlMapping())
.isEqualTo("spring/*.do");
}
@Test
public void getServletUrlMappingWhenHasPathNotEndingSlashReturnsSlashStarPattern() {
assertThat(((DispatcherServletPath) () -> "spring/boot").getServletUrlMapping())
.isEqualTo("spring/boot/*");
}
@Test
public void getServletUrlMappingWhenHasPathEndingWithSlashReturnsSlashStarPattern() {
assertThat(((DispatcherServletPath) () -> "spring/boot/").getServletUrlMapping())
.isEqualTo("spring/boot/*");
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2012-2018 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.autoconfigure.web.servlet;
import java.util.Collections;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.web.servlet.DispatcherServlet;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DispatcherServletRegistrationBean}.
*
* @author Phillip Webb
*/
public class DispatcherServletRegistrationBeanTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void createWhenPathIsNullThrowsException() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Path must not be null");
new DispatcherServletRegistrationBean(new DispatcherServlet(), null);
}
@Test
public void getPathReturnsPath() {
DispatcherServletRegistrationBean bean = new DispatcherServletRegistrationBean(
new DispatcherServlet(), "/test");
assertThat(bean.getPath()).isEqualTo("/test");
}
@Test
public void getUrlMappingsReturnsSinglePathMappedPattern() {
DispatcherServletRegistrationBean bean = new DispatcherServletRegistrationBean(
new DispatcherServlet(), "/test");
assertThat(bean.getUrlMappings()).containsOnly("/test/*");
}
@Test
public void setUrlMappingsCannotBeCalled() {
DispatcherServletRegistrationBean bean = new DispatcherServletRegistrationBean(
new DispatcherServlet(), "/test");
this.thrown.expect(UnsupportedOperationException.class);
bean.setUrlMappings(Collections.emptyList());
}
@Test
public void addUrlMappingsCannotBeCalled() {
DispatcherServletRegistrationBean bean = new DispatcherServletRegistrationBean(
new DispatcherServlet(), "/test");
this.thrown.expect(UnsupportedOperationException.class);
bean.addUrlMappings("/test");
}
}

View File

@@ -20,6 +20,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.test.rule.OutputCapture;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
@@ -39,7 +40,9 @@ import static org.assertj.core.api.Assertions.assertThat;
public class ErrorMvcAutoConfigurationTests {
private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ErrorMvcAutoConfiguration.class));
.withConfiguration(
AutoConfigurations.of(DispatcherServletAutoConfiguration.class,
ErrorMvcAutoConfiguration.class));
@Rule
public OutputCapture outputCapture = new OutputCapture();