Support path discovery for main dispatcher servlet

Add an `DispatcherServletPath` interface which provides a much more
consistent way to discover the path of the main dispatcher servet.

Prior to this commit, auto-configurations would often make use of the
`ServerProperties` class to discover the dispatcher servlet path. This
mechanism isn't very explicit and also makes it hard for us to relocate
that property in Spring Boot 2.1.

This commit also reverts most of fddc9e9c7e since it is now clear that
the supporting multiple dispatcher servlet paths will be much more
involved that we originally anticipated.

Closes gh-13834
This commit is contained in:
Phillip Webb
2018-07-24 16:35:37 +01:00
parent d37e717500
commit 9a9111af21
22 changed files with 501 additions and 260 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.ServerProperties;
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<ServerProperties> {
extends ApplicationContextRequestMatcher<DispatcherServletPath> {
private final Set<StaticResourceLocation> locations;
private volatile RequestMatcher delegate;
private StaticResourceRequestMatcher(Set<StaticResourceLocation> locations) {
super(ServerProperties.class);
super(DispatcherServletPath.class);
this.locations = locations;
}
@@ -134,25 +134,26 @@ public final class StaticResourceRequest {
}
@Override
protected void initialized(Supplier<ServerProperties> serverProperties) {
protected void initialized(
Supplier<DispatcherServletPath> dispatcherServletPath) {
this.delegate = new OrRequestMatcher(
getDelegateMatchers(serverProperties.get()));
getDelegateMatchers(dispatcherServletPath.get()));
}
private List<RequestMatcher> getDelegateMatchers(
ServerProperties serverProperties) {
return getPatterns(serverProperties).map(AntPathRequestMatcher::new)
DispatcherServletPath dispatcherServletPath) {
return getPatterns(dispatcherServletPath).map(AntPathRequestMatcher::new)
.collect(Collectors.toList());
}
private Stream<String> getPatterns(ServerProperties 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<ServerProperties> context) {
Supplier<DispatcherServletPath> context) {
return this.delegate.matches(request);
}

View File

@@ -269,6 +269,13 @@ public class ServerProperties {
return this.session;
}
/**
* Return the mapping used to map a servlet to the path.
* @return the servlet mapping
* @deprecated since 2.0.4 in favor of
* {@link org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath#getServletUrlMapping}
*/
@Deprecated
public String getServletMapping() {
if (this.path.equals("") || this.path.equals("/")) {
return "/";
@@ -282,6 +289,14 @@ public class ServerProperties {
return this.path + "/*";
}
/**
* Return a path relative to the servlet prefix.
* @param path the path to make relative
* @return the relative path
* @deprecated since 2.0.4 in favor of
* {@link org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath#getRelativePath(String)}
*/
@Deprecated
public String getPath(String path) {
String prefix = getServletPrefix();
if (!path.startsWith("/")) {
@@ -290,6 +305,13 @@ public class ServerProperties {
return prefix + path;
}
/**
* Return the servlet prefix.
* @return the servlet prefix
* @deprecated since 2.0.4 in favor of
* {@link org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath#getPrefix()}
*/
@Deprecated
public String getServletPrefix() {
String result = this.path;
int index = result.indexOf('*');
@@ -302,6 +324,14 @@ public class ServerProperties {
return result;
}
/**
* Create a array of relative paths from the given source.
* @param paths the source paths
* @return the relative paths
* @deprecated since 2.0.4 in favor of
* {@link org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath#getRelativePath(String)}
*/
@Deprecated
public String[] getPathsArray(Collection<String> paths) {
String[] result = new String[paths.size()];
int i = 0;
@@ -311,6 +341,14 @@ public class ServerProperties {
return result;
}
/**
* Create a array of relative paths from the given source.
* @param paths the source paths
* @return the relative paths
* @deprecated since 2.0.4 in favor of
* {@link org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath#getRelativePath(String)}
*/
@Deprecated
public String[] getPathsArray(String[] paths) {
String[] result = new String[paths.length];
int i = 0;

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;
@@ -139,11 +137,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.serverProperties.getServlet().getServletMapping());
DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(
dispatcherServlet, this.serverProperties.getServlet().getPath());
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(
this.webMvcProperties.getServlet().getLoadOnStartup());
@@ -153,15 +150,6 @@ public class DispatcherServletAutoConfiguration {
return registration;
}
@Bean
@ConditionalOnMissingBean(DispatcherServletPathProvider.class)
@ConditionalOnSingleCandidate(DispatcherServlet.class)
public DispatcherServletPathProvider dispatcherServletPathProvider() {
return () -> Collections.singleton(
DispatcherServletRegistrationConfiguration.this.serverProperties
.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.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.server.ErrorPage;
@@ -94,11 +95,15 @@ public class ErrorMvcAutoConfiguration {
private final ServerProperties serverProperties;
private final DispatcherServletPath dispatcherServletPath;
private final List<ErrorViewResolver> errorViewResolvers;
public ErrorMvcAutoConfiguration(ServerProperties serverProperties,
DispatcherServletPath dispatcherServletPath,
ObjectProvider<List<ErrorViewResolver>> errorViewResolversProvider) {
this.serverProperties = serverProperties;
this.dispatcherServletPath = dispatcherServletPath;
this.errorViewResolvers = errorViewResolversProvider.getIfAvailable();
}
@@ -118,7 +123,7 @@ public class ErrorMvcAutoConfiguration {
@Bean
public ErrorPageCustomizer errorPageCustomizer() {
return new ErrorPageCustomizer(this.serverProperties);
return new ErrorPageCustomizer(this.serverProperties, this.dispatcherServletPath);
}
@Bean
@@ -327,15 +332,18 @@ public class ErrorMvcAutoConfiguration {
private final ServerProperties properties;
protected ErrorPageCustomizer(ServerProperties properties) {
private final DispatcherServletPath dispatcherServletPath;
protected ErrorPageCustomizer(ServerProperties properties,
DispatcherServletPath dispatcherServletPath) {
this.properties = properties;
this.dispatcherServletPath = dispatcherServletPath;
}
@Override
public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
ErrorPage errorPage = new ErrorPage(
this.properties.getServlet().getServletPrefix()
+ this.properties.getError().getPath());
ErrorPage errorPage = new ErrorPage(this.dispatcherServletPath
.getRelativePath(this.properties.getError().getPath()));
errorPageRegistry.addErrorPages(errorPage);
}

View File

@@ -25,6 +25,7 @@ import org.junit.rules.ExpectedException;
import org.springframework.boot.autoconfigure.security.StaticResourceLocation;
import org.springframework.boot.autoconfigure.web.ServerProperties;
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;
@@ -96,15 +97,20 @@ public class StaticResourceRequestTests {
}
private RequestMatcherAssert assertMatcher(RequestMatcher matcher) {
DispatcherServletPath dispatcherServletPath = () -> "";
StaticWebApplicationContext context = new StaticWebApplicationContext();
context.registerBean(ServerProperties.class);
context.registerBean(DispatcherServletPath.class, () -> dispatcherServletPath);
return assertThat(new RequestMatcherAssert(context, matcher));
}
private RequestMatcherAssert assertMatcher(RequestMatcher matcher,
ServerProperties serverProperties) {
DispatcherServletPath dispatcherServletPath = () -> serverProperties.getServlet()
.getPath();
StaticWebApplicationContext context = new StaticWebApplicationContext();
context.registerBean(ServerProperties.class, () -> serverProperties);
context.registerBean(DispatcherServletPath.class, () -> dispatcherServletPath);
return assertThat(new RequestMatcherAssert(context, matcher));
}

View File

@@ -79,6 +79,7 @@ public class ServerPropertiesTests {
}
@Test
@Deprecated
public void testServletPathAsMapping() {
bind("server.servlet.path", "/foo/*");
assertThat(this.properties.getServlet().getServletMapping()).isEqualTo("/foo/*");
@@ -86,6 +87,7 @@ public class ServerPropertiesTests {
}
@Test
@Deprecated
public void testServletPathAsPrefix() {
bind("server.servlet.path", "/foo");
assertThat(this.properties.getServlet().getServletMapping()).isEqualTo("/foo/*");

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("server.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();