diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java index eb2b9308218..2c181c594b4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java @@ -53,8 +53,8 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { @Override - protected void addInterceptors(InterceptorRegistry registry) { - this.configurers.addInterceptors(registry); + protected void configurePathMatch(PathMatchConfigurer configurer) { + this.configurers.configurePathMatch(configurer); } @Override @@ -63,13 +63,33 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { } @Override - public void configureAsyncSupport(AsyncSupportConfigurer configurer) { + protected void configureAsyncSupport(AsyncSupportConfigurer configurer) { this.configurers.configureAsyncSupport(configurer); } @Override - public void configurePathMatch(PathMatchConfigurer configurer) { - this.configurers.configurePathMatch(configurer); + protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + this.configurers.configureDefaultServletHandling(configurer); + } + + @Override + protected void addFormatters(FormatterRegistry registry) { + this.configurers.addFormatters(registry); + } + + @Override + protected void addInterceptors(InterceptorRegistry registry) { + this.configurers.addInterceptors(registry); + } + + @Override + protected void addResourceHandlers(ResourceHandlerRegistry registry) { + this.configurers.addResourceHandlers(registry); + } + + @Override + protected void addCorsMappings(CorsRegistry registry) { + this.configurers.addCorsMappings(registry); } @Override @@ -82,16 +102,6 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { this.configurers.configureViewResolvers(registry); } - @Override - protected void addResourceHandlers(ResourceHandlerRegistry registry) { - this.configurers.addResourceHandlers(registry); - } - - @Override - protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { - this.configurers.configureDefaultServletHandling(configurer); - } - @Override protected void addArgumentResolvers(List argumentResolvers) { this.configurers.addArgumentResolvers(argumentResolvers); @@ -113,8 +123,13 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { } @Override - protected void addFormatters(FormatterRegistry registry) { - this.configurers.addFormatters(registry); + protected void configureHandlerExceptionResolvers(List exceptionResolvers) { + this.configurers.configureHandlerExceptionResolvers(exceptionResolvers); + } + + @Override + protected void extendHandlerExceptionResolvers(List exceptionResolvers) { + this.configurers.extendHandlerExceptionResolvers(exceptionResolvers); } @Override @@ -127,19 +142,4 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { return this.configurers.getMessageCodesResolver(); } - @Override - protected void configureHandlerExceptionResolvers(List exceptionResolvers) { - this.configurers.configureHandlerExceptionResolvers(exceptionResolvers); - } - - @Override - protected void extendHandlerExceptionResolvers(List exceptionResolvers) { - this.configurers.extendHandlerExceptionResolvers(exceptionResolvers); - } - - @Override - protected void addCorsMappings(CorsRegistry registry) { - this.configurers.addCorsMappings(registry); - } - } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java index 389ffd87540..708e507d242 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java @@ -17,13 +17,13 @@ package org.springframework.web.servlet.config.annotation; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; -import javax.xml.transform.Source; import com.fasterxml.jackson.databind.ObjectMapper; @@ -86,10 +86,8 @@ import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionRes import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; import org.springframework.web.servlet.mvc.method.annotation.JsonViewRequestBodyAdvice; import org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice; -import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver; import org.springframework.web.servlet.resource.ResourceUrlProvider; import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor; @@ -233,6 +231,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv return this.servletContext; } + /** * Return a {@link RequestMappingHandlerMapping} ordered at 0 for mapping * requests to annotated controllers. @@ -255,11 +254,13 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv if (configurer.isUseTrailingSlashMatch() != null) { handlerMapping.setUseTrailingSlashMatch(configurer.isUseTrailingSlashMatch()); } - if (configurer.getPathMatcher() != null) { - handlerMapping.setPathMatcher(configurer.getPathMatcher()); + UrlPathHelper pathHelper = configurer.getUrlPathHelper(); + if (pathHelper != null) { + handlerMapping.setUrlPathHelper(pathHelper); } - if (configurer.getUrlPathHelper() != null) { - handlerMapping.setUrlPathHelper(configurer.getUrlPathHelper()); + PathMatcher pathMatcher = configurer.getPathMatcher(); + if (pathMatcher != null) { + handlerMapping.setPathMatcher(pathMatcher); } return handlerMapping; @@ -315,7 +316,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv * @see PathMatchConfigurer * @since 4.0.3 */ - public void configurePathMatch(PathMatchConfigurer configurer) { + protected void configurePathMatch(PathMatchConfigurer configurer) { } /** @@ -339,7 +340,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv } protected Map getDefaultMediaTypes() { - Map map = new HashMap<>(); + Map map = new HashMap<>(4); if (romePresent) { map.put("atom", MediaType.APPLICATION_ATOM_XML); map.put("rss", MediaType.valueOf("application/rss+xml")); @@ -487,18 +488,12 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv adapter.setCustomReturnValueHandlers(getReturnValueHandlers()); if (jackson2Present) { - List requestBodyAdvices = new ArrayList<>(); - requestBodyAdvices.add(new JsonViewRequestBodyAdvice()); - adapter.setRequestBodyAdvice(requestBodyAdvices); - - List> responseBodyAdvices = new ArrayList<>(); - responseBodyAdvices.add(new JsonViewResponseBodyAdvice()); - adapter.setResponseBodyAdvice(responseBodyAdvices); + adapter.setRequestBodyAdvice(Collections.singletonList(new JsonViewRequestBodyAdvice())); + adapter.setResponseBodyAdvice(Collections.singletonList(new JsonViewResponseBodyAdvice())); } AsyncSupportConfigurer configurer = new AsyncSupportConfigurer(); configureAsyncSupport(configurer); - if (configurer.getTaskExecutor() != null) { adapter.setTaskExecutor(configurer.getTaskExecutor()); } @@ -531,6 +526,20 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv return initializer; } + /** + * Override this method to provide a custom {@link MessageCodesResolver}. + */ + protected MessageCodesResolver getMessageCodesResolver() { + return null; + } + + /** + * Override this method to configure asynchronous request processing options. + * @see AsyncSupportConfigurer + */ + protected void configureAsyncSupport(AsyncSupportConfigurer configurer) { + } + /** * Return a {@link FormattingConversionService} for use with annotated * controller methods and the {@code spring:eval} JSP tag. @@ -543,6 +552,12 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv return conversionService; } + /** + * Override this method to add custom {@link Converter}s and {@link Formatter}s. + */ + protected void addFormatters(FormatterRegistry registry) { + } + /** * Return a global {@link Validator} instance for example for validating * {@code @ModelAttribute} and {@code @RequestBody} method arguments. @@ -576,6 +591,13 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv return validator; } + /** + * Override this method to provide a custom {@link Validator}. + */ + protected Validator getValidator() { + return null; + } + /** * Return a global {@link PathMatcher} instance for path matching * patterns in {@link HandlerMapping}s. @@ -602,26 +624,8 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv */ @Bean public UrlPathHelper mvcUrlPathHelper() { - if (getPathMatchConfigurer().getUrlPathHelper() != null) { - return getPathMatchConfigurer().getUrlPathHelper(); - } - else { - return new UrlPathHelper(); - } - } - - /** - * Override this method to provide a custom {@link Validator}. - */ - protected Validator getValidator() { - return null; - } - - /** - * Override this method to provide a custom {@link MessageCodesResolver}. - */ - protected MessageCodesResolver getMessageCodesResolver() { - return null; + UrlPathHelper pathHelper = getPathMatchConfigurer().getUrlPathHelper(); + return (pathHelper != null ? pathHelper : new UrlPathHelper()); } /** @@ -762,19 +766,6 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv } } - /** - * Override this method to add custom {@link Converter}s and {@link Formatter}s. - */ - protected void addFormatters(FormatterRegistry registry) { - } - - /** - * Override this method to configure asynchronous request processing options. - * @see AsyncSupportConfigurer - */ - public void configureAsyncSupport(AsyncSupportConfigurer configurer) { - } - /** * Return an instance of {@link CompositeUriComponentsContributor} for use with * {@link org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder}. @@ -817,11 +808,9 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv public HandlerExceptionResolver handlerExceptionResolver() { List exceptionResolvers = new ArrayList<>(); configureHandlerExceptionResolvers(exceptionResolvers); - if (exceptionResolvers.isEmpty()) { addDefaultHandlerExceptionResolvers(exceptionResolvers); } - extendHandlerExceptionResolvers(exceptionResolvers); HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite(); composite.setOrder(0); @@ -871,9 +860,8 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv exceptionHandlerResolver.setCustomArgumentResolvers(getArgumentResolvers()); exceptionHandlerResolver.setCustomReturnValueHandlers(getReturnValueHandlers()); if (jackson2Present) { - List> interceptors = new ArrayList<>(); - interceptors.add(new JsonViewResponseBodyAdvice()); - exceptionHandlerResolver.setResponseBodyAdvice(interceptors); + exceptionHandlerResolver.setResponseBodyAdvice( + Collections.singletonList(new JsonViewResponseBodyAdvice())); } exceptionHandlerResolver.setApplicationContext(this.applicationContext); exceptionHandlerResolver.afterPropertiesSet(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java index 93533331350..ca00aec989d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java @@ -46,12 +46,104 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl */ public interface WebMvcConfigurer { + /** + * Helps with configuring HandlerMappings path matching options such as trailing slash match, + * suffix registration, path matcher and path helper. + * Configured path matcher and path helper instances are shared for: + *
    + *
  • RequestMappings
  • + *
  • ViewControllerMappings
  • + *
  • ResourcesMappings
  • + *
+ * @since 4.0.3 + */ + void configurePathMatch(PathMatchConfigurer configurer); + + /** + * Configure content negotiation options. + */ + void configureContentNegotiation(ContentNegotiationConfigurer configurer); + + /** + * Configure asynchronous request handling options. + */ + void configureAsyncSupport(AsyncSupportConfigurer configurer); + + /** + * Configure a handler to delegate unhandled requests by forwarding to the + * Servlet container's "default" servlet. A common use case for this is when + * the {@link DispatcherServlet} is mapped to "/" thus overriding the + * Servlet container's default handling of static resources. + */ + void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer); + /** * Add {@link Converter}s and {@link Formatter}s in addition to the ones * registered by default. */ void addFormatters(FormatterRegistry registry); + /** + * Add Spring MVC lifecycle interceptors for pre- and post-processing of + * controller method invocations. Interceptors can be registered to apply + * to all requests or be limited to a subset of URL patterns. + *

Note that interceptors registered here only apply to + * controllers and not to resource handler requests. To intercept requests for + * static resources either declare a + * {@link org.springframework.web.servlet.handler.MappedInterceptor MappedInterceptor} + * bean or switch to advanced configuration mode by extending + * {@link org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport + * WebMvcConfigurationSupport} and then override {@code resourceHandlerMapping}. + */ + void addInterceptors(InterceptorRegistry registry); + + /** + * Add handlers to serve static resources such as images, js, and, css + * files from specific locations under web application root, the classpath, + * and others. + */ + void addResourceHandlers(ResourceHandlerRegistry registry); + + /** + * Configure cross origin requests processing. + * @since 4.2 + */ + void addCorsMappings(CorsRegistry registry); + + /** + * Configure simple automated controllers pre-configured with the response + * status code and/or a view to render the response body. This is useful in + * cases where there is no need for custom controller logic -- e.g. render a + * home page, perform simple site URL redirects, return a 404 status with + * HTML content, a 204 with no content, and more. + */ + void addViewControllers(ViewControllerRegistry registry); + + /** + * Configure view resolvers to translate String-based view names returned from + * controllers into concrete {@link org.springframework.web.servlet.View} + * implementations to perform rendering with. + */ + void configureViewResolvers(ViewResolverRegistry registry); + + /** + * Add resolvers to support custom controller method argument types. + *

This does not override the built-in support for resolving handler + * method arguments. To customize the built-in support for argument + * resolution, configure {@link RequestMappingHandlerAdapter} directly. + * @param argumentResolvers initially an empty list + */ + void addArgumentResolvers(List argumentResolvers); + + /** + * Add handlers to support custom controller method return value types. + *

Using this option does not override the built-in support for handling + * return values. To customize the built-in support for handling return + * values, configure RequestMappingHandlerAdapter directly. + * @param returnValueHandlers initially an empty list + */ + void addReturnValueHandlers(List returnValueHandlers); + /** * Configure the {@link HttpMessageConverter}s to use for reading or writing * to the body of the request or response. If no converters are added, a @@ -73,55 +165,6 @@ public interface WebMvcConfigurer { */ void extendMessageConverters(List> converters); - /** - * Provide a custom {@link Validator} instead of the one created by default. - * The default implementation, assuming JSR-303 is on the classpath, is: - * {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}. - * Leave the return value as {@code null} to keep the default. - */ - Validator getValidator(); - - /** - * Configure content negotiation options. - */ - void configureContentNegotiation(ContentNegotiationConfigurer configurer); - - /** - * Configure asynchronous request handling options. - */ - void configureAsyncSupport(AsyncSupportConfigurer configurer); - - /** - * Helps with configuring HandlerMappings path matching options such as trailing slash match, - * suffix registration, path matcher and path helper. - * Configured path matcher and path helper instances are shared for: - *

    - *
  • RequestMappings
  • - *
  • ViewControllerMappings
  • - *
  • ResourcesMappings
  • - *
- * @since 4.0.3 - */ - void configurePathMatch(PathMatchConfigurer configurer); - - /** - * Add resolvers to support custom controller method argument types. - *

This does not override the built-in support for resolving handler - * method arguments. To customize the built-in support for argument - * resolution, configure {@link RequestMappingHandlerAdapter} directly. - * @param argumentResolvers initially an empty list - */ - void addArgumentResolvers(List argumentResolvers); - - /** - * Add handlers to support custom controller method return value types. - *

Using this option does not override the built-in support for handling - * return values. To customize the built-in support for handling return - * values, configure RequestMappingHandlerAdapter directly. - * @param returnValueHandlers initially an empty list - */ - void addReturnValueHandlers(List returnValueHandlers); - /** * Configure the {@link HandlerExceptionResolver}s to handle unresolved * controller exceptions. If no resolvers are added to the list, default @@ -140,18 +183,12 @@ public interface WebMvcConfigurer { void extendHandlerExceptionResolvers(List exceptionResolvers); /** - * Add Spring MVC lifecycle interceptors for pre- and post-processing of - * controller method invocations. Interceptors can be registered to apply - * to all requests or be limited to a subset of URL patterns. - *

Note that interceptors registered here only apply to - * controllers and not to resource handler requests. To intercept requests for - * static resources either declare a - * {@link org.springframework.web.servlet.handler.MappedInterceptor MappedInterceptor} - * bean or switch to advanced configuration mode by extending - * {@link org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport - * WebMvcConfigurationSupport} and then override {@code resourceHandlerMapping}. + * Provide a custom {@link Validator} instead of the one created by default. + * The default implementation, assuming JSR-303 is on the classpath, is: + * {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}. + * Leave the return value as {@code null} to keep the default. */ - void addInterceptors(InterceptorRegistry registry); + Validator getValidator(); /** * Provide a custom {@link MessageCodesResolver} for building message codes @@ -160,41 +197,4 @@ public interface WebMvcConfigurer { */ MessageCodesResolver getMessageCodesResolver(); - /** - * Configure simple automated controllers pre-configured with the response - * status code and/or a view to render the response body. This is useful in - * cases where there is no need for custom controller logic -- e.g. render a - * home page, perform simple site URL redirects, return a 404 status with - * HTML content, a 204 with no content, and more. - */ - void addViewControllers(ViewControllerRegistry registry); - - /** - * Configure view resolvers to translate String-based view names returned from - * controllers into concrete {@link org.springframework.web.servlet.View} - * implementations to perform rendering with. - */ - void configureViewResolvers(ViewResolverRegistry registry); - - /** - * Add handlers to serve static resources such as images, js, and, css - * files from specific locations under web application root, the classpath, - * and others. - */ - void addResourceHandlers(ResourceHandlerRegistry registry); - - /** - * Configure a handler to delegate unhandled requests by forwarding to the - * Servlet container's "default" servlet. A common use case for this is when - * the {@link DispatcherServlet} is mapped to "/" thus overriding the - * Servlet container's default handling of static resources. - */ - void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer); - - /** - * Configure cross origin requests processing. - * @since 4.2 - */ - void addCorsMappings(CorsRegistry registry); - } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java index 1c9e3e0c7e5..3d1c28845e3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -28,7 +28,7 @@ import org.springframework.web.servlet.HandlerExceptionResolver; /** * An implementation of {@link WebMvcConfigurer} with empty methods allowing - * sub-classes to override only the methods they're interested in. + * subclasses to override only the methods they're interested in. * * @author Rossen Stoyanchev * @since 3.1 @@ -40,32 +40,7 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { *

This implementation is empty. */ @Override - public void addFormatters(FormatterRegistry registry) { - } - - /** - * {@inheritDoc} - *

This implementation is empty. - */ - @Override - public void configureMessageConverters(List> converters) { - } - - /** - * {@inheritDoc} - *

This implementation is empty. - */ - @Override - public void extendMessageConverters(List> converters) { - } - - /** - * {@inheritDoc} - *

This implementation returns {@code null} - */ - @Override - public Validator getValidator() { - return null; + public void configurePathMatch(PathMatchConfigurer configurer) { } /** @@ -89,7 +64,7 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { *

This implementation is empty. */ @Override - public void configurePathMatch(PathMatchConfigurer configurer) { + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { } /** @@ -97,40 +72,7 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { *

This implementation is empty. */ @Override - public void addArgumentResolvers(List argumentResolvers) { - } - - /** - * {@inheritDoc} - *

This implementation is empty. - */ - @Override - public void addReturnValueHandlers(List returnValueHandlers) { - } - - /** - * {@inheritDoc} - *

This implementation is empty. - */ - @Override - public void configureHandlerExceptionResolvers(List exceptionResolvers) { - } - - /** - * {@inheritDoc} - *

This implementation is empty. - */ - @Override - public void extendHandlerExceptionResolvers(List exceptionResolvers) { - } - - /** - * {@inheritDoc} - *

This implementation is empty. - */ - @Override - public MessageCodesResolver getMessageCodesResolver() { - return null; + public void addFormatters(FormatterRegistry registry) { } /** @@ -141,6 +83,22 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { } + /** + * {@inheritDoc} + *

This implementation is empty. + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + } + + /** + * {@inheritDoc} + *

This implementation is empty. + */ + @Override + public void addCorsMappings(CorsRegistry registry) { + } + /** * {@inheritDoc} *

This implementation is empty. @@ -162,7 +120,7 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { *

This implementation is empty. */ @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { + public void addArgumentResolvers(List argumentResolvers) { } /** @@ -170,7 +128,7 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { *

This implementation is empty. */ @Override - public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + public void addReturnValueHandlers(List returnValueHandlers) { } /** @@ -178,7 +136,49 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { *

This implementation is empty. */ @Override - public void addCorsMappings(CorsRegistry registry) { + public void configureMessageConverters(List> converters) { + } + + /** + * {@inheritDoc} + *

This implementation is empty. + */ + @Override + public void extendMessageConverters(List> converters) { + } + + /** + * {@inheritDoc} + *

This implementation is empty. + */ + @Override + public void configureHandlerExceptionResolvers(List exceptionResolvers) { + } + + /** + * {@inheritDoc} + *

This implementation is empty. + */ + @Override + public void extendHandlerExceptionResolvers(List exceptionResolvers) { + } + + /** + * {@inheritDoc} + *

This implementation returns {@code null}. + */ + @Override + public Validator getValidator() { + return null; + } + + /** + * {@inheritDoc} + *

This implementation returns {@code null}. + */ + @Override + public MessageCodesResolver getMessageCodesResolver() { + return null; } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java index 8bada966664..c2b62ee2d3c 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java @@ -21,6 +21,7 @@ import java.util.List; import org.springframework.format.FormatterRegistry; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.util.CollectionUtils; import org.springframework.validation.MessageCodesResolver; import org.springframework.validation.Validator; import org.springframework.web.method.support.HandlerMethodArgumentResolver; @@ -35,18 +36,20 @@ import org.springframework.web.servlet.HandlerExceptionResolver; */ class WebMvcConfigurerComposite implements WebMvcConfigurer { - private final List delegates = new ArrayList<>(); + private final List delegates = new ArrayList(); + public void addWebMvcConfigurers(List configurers) { - if (configurers != null) { + if (!CollectionUtils.isEmpty(configurers)) { this.delegates.addAll(configurers); } } + @Override - public void addFormatters(FormatterRegistry registry) { + public void configurePathMatch(PathMatchConfigurer configurer) { for (WebMvcConfigurer delegate : this.delegates) { - delegate.addFormatters(registry); + delegate.configurePathMatch(configurer); } } @@ -65,51 +68,16 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer { } @Override - public void configurePathMatch(PathMatchConfigurer configurer) { + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { for (WebMvcConfigurer delegate : this.delegates) { - delegate.configurePathMatch(configurer); + delegate.configureDefaultServletHandling(configurer); } } @Override - public void configureMessageConverters(List> converters) { + public void addFormatters(FormatterRegistry registry) { for (WebMvcConfigurer delegate : this.delegates) { - delegate.configureMessageConverters(converters); - } - } - - @Override - public void extendMessageConverters(List> converters) { - for (WebMvcConfigurer delegate : this.delegates) { - delegate.extendMessageConverters(converters); - } - } - - @Override - public void addArgumentResolvers(List argumentResolvers) { - for (WebMvcConfigurer delegate : this.delegates) { - delegate.addArgumentResolvers(argumentResolvers); - } - } - - @Override - public void addReturnValueHandlers(List returnValueHandlers) { - for (WebMvcConfigurer delegate : this.delegates) { - delegate.addReturnValueHandlers(returnValueHandlers); - } - } - - @Override - public void configureHandlerExceptionResolvers(List exceptionResolvers) { - for (WebMvcConfigurer delegate : this.delegates) { - delegate.configureHandlerExceptionResolvers(exceptionResolvers); - } - } - - @Override - public void extendHandlerExceptionResolvers(List exceptionResolvers) { - for (WebMvcConfigurer delegate : this.delegates) { - delegate.extendHandlerExceptionResolvers(exceptionResolvers); + delegate.addFormatters(registry); } } @@ -120,6 +88,20 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer { } } + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + for (WebMvcConfigurer delegate : this.delegates) { + delegate.addResourceHandlers(registry); + } + } + + @Override + public void addCorsMappings(CorsRegistry registry) { + for (WebMvcConfigurer delegate : this.delegates) { + delegate.addCorsMappings(registry); + } + } + @Override public void addViewControllers(ViewControllerRegistry registry) { for (WebMvcConfigurer delegate : this.delegates) { @@ -135,61 +117,77 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer { } @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { + public void addArgumentResolvers(List argumentResolvers) { for (WebMvcConfigurer delegate : this.delegates) { - delegate.addResourceHandlers(registry); + delegate.addArgumentResolvers(argumentResolvers); } } @Override - public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + public void addReturnValueHandlers(List returnValueHandlers) { for (WebMvcConfigurer delegate : this.delegates) { - delegate.configureDefaultServletHandling(configurer); + delegate.addReturnValueHandlers(returnValueHandlers); + } + } + + @Override + public void configureMessageConverters(List> converters) { + for (WebMvcConfigurer delegate : this.delegates) { + delegate.configureMessageConverters(converters); + } + } + + @Override + public void extendMessageConverters(List> converters) { + for (WebMvcConfigurer delegate : this.delegates) { + delegate.extendMessageConverters(converters); + } + } + + @Override + public void configureHandlerExceptionResolvers(List exceptionResolvers) { + for (WebMvcConfigurer delegate : this.delegates) { + delegate.configureHandlerExceptionResolvers(exceptionResolvers); + } + } + + @Override + public void extendHandlerExceptionResolvers(List exceptionResolvers) { + for (WebMvcConfigurer delegate : this.delegates) { + delegate.extendHandlerExceptionResolvers(exceptionResolvers); } } @Override public Validator getValidator() { - List candidates = new ArrayList<>(); + Validator selected = null; for (WebMvcConfigurer configurer : this.delegates) { Validator validator = configurer.getValidator(); if (validator != null) { - candidates.add(validator); + if (selected != null) { + throw new IllegalStateException("No unique Validator found: {" + + selected + ", " + validator + "}"); + } + selected = validator; } } - return selectSingleInstance(candidates, Validator.class); - } - - @Override - public void addCorsMappings(CorsRegistry registry) { - for (WebMvcConfigurer delegate : this.delegates) { - delegate.addCorsMappings(registry); - } - } - - private T selectSingleInstance(List instances, Class instanceType) { - if (instances.size() > 1) { - throw new IllegalStateException( - "Only one [" + instanceType + "] was expected but multiple instances were provided: " + instances); - } - else if (instances.size() == 1) { - return instances.get(0); - } - else { - return null; - } + return selected; } @Override public MessageCodesResolver getMessageCodesResolver() { - List candidates = new ArrayList<>(); + MessageCodesResolver selected = null; for (WebMvcConfigurer configurer : this.delegates) { MessageCodesResolver messageCodesResolver = configurer.getMessageCodesResolver(); if (messageCodesResolver != null) { - candidates.add(messageCodesResolver); + if (selected != null) { + throw new IllegalStateException("No unique MessageCodesResolver found: {" + + selected + ", " + messageCodesResolver + "}"); + } + selected = messageCodesResolver; } } - return selectSingleInstance(candidates, MessageCodesResolver.class); + return selected; } }