docs
Java-based configuration for Spring MVC including the @EnableWebMvc annotation and WebMvcConfigurer interface for customizing framework behavior, along with configuration support classes.
Enables Spring MVC configuration by importing the Spring MVC configuration from WebMvcConfigurationSupport. This annotation should be added to an @Configuration class.
/**
* Adding this annotation to an @Configuration class imports the Spring MVC configuration
* from WebMvcConfigurationSupport, which provides default configuration for Spring MVC
* applications including:
* - Registering Spring MVC infrastructure beans
* - Configuring the DispatcherServlet
* - Setting up default converters and formatters
* - Enabling annotation-driven controller methods
*
* To customize the imported configuration, implement WebMvcConfigurer and override
* the needed methods.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}Usage Example:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.web")
public class WebConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
}
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}Defines callback methods to customize the Java-based configuration for Spring MVC enabled via @EnableWebMvc. All methods have empty default implementations allowing selective overriding.
/**
* Defines callback methods to customize the Java-based configuration for Spring MVC
* enabled via @EnableWebMvc.
*
* @EnableWebMvc-annotated configuration classes may implement this interface to be called back
* and given a chance to customize the default configuration.
*/
public interface WebMvcConfigurer {
/**
* Help with configuring HandlerMappings path matching options such as whether to use
* parsed PathPatterns or String pattern matching with PathMatcher, whether to match
* trailing slashes, and more.
*
* @param configurer the PathMatchConfigurer instance
*/
default void configurePathMatch(PathMatchConfigurer configurer) {}
/**
* Configure content negotiation options.
*
* @param configurer the ContentNegotiationConfigurer instance
*/
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}
/**
* Configure API versioning options. This is a new method added in Spring MVC 7.0.
*
* @param configurer the ApiVersionConfigurer instance
* @since 7.0
*/
default void configureApiVersioning(ApiVersionConfigurer configurer) {}
/**
* Configure asynchronous request handling options.
*
* @param configurer the AsyncSupportConfigurer instance
*/
default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}
/**
* Configure a handler to delegate unhandled requests by forwarding to the
* Servlet container's "default" servlet.
*
* @param configurer the DefaultServletHandlerConfigurer instance
*/
default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}
/**
* Add Converters and Formatters in addition to the ones registered by default.
*
* @param registry the FormatterRegistry instance
*/
default void addFormatters(FormatterRegistry registry) {}
/**
* Add Spring MVC lifecycle interceptors for pre- and post-processing of
* controller method invocations and resource handler requests.
* Interceptors can be registered to apply to all requests or be limited
* to a subset of URL patterns.
*
* @param registry the InterceptorRegistry instance
*/
default 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.
*
* @param registry the ResourceHandlerRegistry instance
*/
default void addResourceHandlers(ResourceHandlerRegistry registry) {}
/**
* Configure cross origin requests processing.
*
* @param registry the CorsRegistry instance
*/
default 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.
*
* @param registry the ViewControllerRegistry instance
*/
default void addViewControllers(ViewControllerRegistry registry) {}
/**
* Configure view resolvers to translate String-based view names returned from
* controllers into concrete View implementations to perform rendering with.
*
* @param registry the ViewResolverRegistry instance
*/
default 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 RequestMappingHandlerAdapter directly.
*
* @param resolvers initially an empty list
*/
default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {}
/**
* 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 handlers initially an empty list
*/
default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {}
/**
* Configure the HttpMessageConverters for reading from the request body and for
* writing to the response body in @RequestBody/@ResponseBody methods and
* HttpEntity/ResponseEntity methods.
*
* By default, all built-in converters are configured as long as the corresponding
* 3rd party libraries are present on the classpath. Use this method to replace the
* default list of converters or to add custom converters.
*
* Note: This method has been updated in Spring MVC 7.0 to use HttpMessageConverters.ServerBuilder
* instead of directly accepting a List of converters.
*
* @param builder the builder for configuring message converters
* @since 7.0
*/
default void configureMessageConverters(HttpMessageConverters.ServerBuilder builder) {}
/**
* Configure exception resolvers.
* The given list starts out empty. If it is left empty, the framework
* configures a default set of resolvers. Or if any exception resolvers are
* added to the list, then the application effectively takes over and must
* provide, fully initialized, exception resolvers.
* Alternatively you can use extendHandlerExceptionResolvers which allows
* you to extend or modify the list of exception resolvers configured by default.
*
* @param resolvers initially an empty list
*/
default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}
/**
* Extending or modify the list of exception resolvers configured by default.
* This can be useful for inserting a custom exception resolver without
* interfering with default ones.
*
* @param resolvers the list of configured resolvers to extend
*/
default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}
/**
* Provide a custom Validator instead of the one created by default.
* The default implementation, assuming JSR-303 is on the classpath, is:
* OptionalValidatorFactoryBean. Leave the return value as null to keep the default.
*
* @return the custom Validator, or null for the default
*/
default Validator getValidator() {
return null;
}
/**
* Provide a custom MessageCodesResolver for building message codes from
* data binding and validation error codes. Leave the return value as null
* to keep the default.
*
* @return the custom MessageCodesResolver, or null for the default
*/
default MessageCodesResolver getMessageCodesResolver() {
return null;
}
}Usage Example:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer
.setUseTrailingSlashMatch(true)
.setUrlPathHelper(new UrlPathHelper())
.addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class));
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.favorParameter(true)
.parameterName("mediaType")
.ignoreAcceptHeader(false)
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("json", MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML);
}
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer
.useRequestHeader("X-API-Version")
.useQueryParam("version");
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
configurer
.setDefaultTimeout(30000)
.setTaskExecutor(asyncTaskExecutor());
}
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new DateFormatter("yyyy-MM-dd"));
registry.addConverter(new StringToEnumConverter());
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggingInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/public/**");
registry.addInterceptor(new AuthenticationInterceptor())
.addPathPatterns("/admin/**")
.order(1);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS));
registry.addResourceHandler("/uploads/**")
.addResourceLocations("file:///var/uploads/")
.resourceChain(true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000", "https://example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("home");
registry.addViewController("/login").setViewName("login");
registry.addRedirectViewController("/old", "/new");
registry.addStatusController("/health", HttpStatus.OK);
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.enableContentNegotiation(new MappingJackson2JsonView());
registry.jsp("/WEB-INF/views/", ".jsp");
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new CustomArgumentResolver());
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
handlers.add(new CustomReturnValueHandler());
}
@Override
public void configureMessageConverters(HttpMessageConverters.ServerBuilder builder) {
builder
.json() // Configure JSON converter
.xml() // Configure XML converter
.addConverter(new CustomMessageConverter());
}
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
resolvers.add(0, new CustomExceptionResolver());
}
@Override
public Validator getValidator() {
return new CustomValidator();
}
@Bean
public ThreadPoolTaskExecutor asyncTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(25);
executor.setThreadNamePrefix("async-");
executor.initialize();
return executor;
}
}Base class for providing configuration for Spring MVC applications. Typically imported via @EnableWebMvc. Can be extended directly for advanced customization.
/**
* This is the main class providing the configuration behind the MVC Java config.
* It is typically imported by adding @EnableWebMvc to an application
* @Configuration class. An alternative more advanced option is to extend directly
* from this class and override methods as necessary, remembering to add
* @Configuration to the subclass and @Bean to overridden @Bean methods.
*
* This class registers the following HandlerMappings:
* - RequestMappingHandlerMapping ordered at 0 for mapping requests to annotated controller methods.
* - HandlerMapping ordered at 1 to map URL paths directly to view names.
* - BeanNameUrlHandlerMapping ordered at 2 to map URL paths to controller bean names.
* - HandlerMapping ordered at Integer.MAX_VALUE-1 to serve static resource requests.
* - HandlerMapping ordered at Integer.MAX_VALUE to forward requests to the default servlet.
*
* Registers these HandlerAdapters:
* - RequestMappingHandlerAdapter for processing requests with annotated controller methods.
* - HttpRequestHandlerAdapter for processing requests with HttpRequestHandlers.
* - SimpleControllerHandlerAdapter for processing requests with interface-based Controllers.
*
* Registers a HandlerExceptionResolverComposite with this chain of exception resolvers:
* - ExceptionHandlerExceptionResolver for handling exceptions through @ExceptionHandler methods.
* - ResponseStatusExceptionResolver for exceptions annotated with @ResponseStatus.
* - DefaultHandlerExceptionResolver for resolving known Spring exception types.
*/
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
/**
* Return a RequestMappingHandlerMapping ordered at 0 for mapping requests
* to annotated controllers.
*/
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {}
/**
* Return a RequestMappingHandlerAdapter for processing requests through
* annotated controller methods.
*/
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {}
/**
* Return a FormattingConversionService for use with annotated controllers.
*/
@Bean
public FormattingConversionService mvcConversionService() {}
/**
* Return a global Validator instance for validating @ModelAttribute and
* @RequestBody method arguments.
*/
@Bean
public Validator mvcValidator() {}
/**
* Return a ContentNegotiationManager instance to use to determine requested
* media types in a given request.
*/
@Bean
public ContentNegotiationManager mvcContentNegotiationManager() {}
/**
* Return a handler mapping ordered at 1 to map URL paths directly to
* view names.
*/
@Bean
public HandlerMapping viewControllerHandlerMapping() {}
/**
* Return a BeanNameUrlHandlerMapping ordered at 2 to map URL paths to
* controller bean names.
*/
@Bean
public BeanNameUrlHandlerMapping beanNameHandlerMapping() {}
/**
* Return a handler mapping ordered at Integer.MAX_VALUE-1 with mapped
* resource handlers.
*/
@Bean
public HandlerMapping resourceHandlerMapping() {}
/**
* Return a handler mapping ordered at Integer.MAX_VALUE to forward to the
* default servlet.
*/
@Bean
public HandlerMapping defaultServletHandlerMapping() {}
/**
* Returns a HandlerExceptionResolverComposite containing a list of exception
* resolvers obtained from configureHandlerExceptionResolvers.
*/
@Bean
public HandlerExceptionResolver handlerExceptionResolver() {}
/**
* Return a ViewResolver instance.
*/
@Bean
public ViewResolver mvcViewResolver() {}
/**
* Override this method to configure path matching options.
*/
protected void configurePathMatch(PathMatchConfigurer configurer) {}
/**
* Override this method to configure content negotiation.
*/
protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}
/**
* Override this method to configure asynchronous request processing options.
*/
protected void configureAsyncSupport(AsyncSupportConfigurer configurer) {}
/**
* Override this method to add custom Converters and Formatters.
*/
protected void addFormatters(FormatterRegistry registry) {}
/**
* Override this method to add Spring MVC interceptors.
*/
protected void addInterceptors(InterceptorRegistry registry) {}
/**
* Override this method to add resource handlers.
*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {}
/**
* Override this method to configure cross origin requests processing.
*/
protected void addCorsMappings(CorsRegistry registry) {}
/**
* Override this method to configure view controllers.
*/
protected void addViewControllers(ViewControllerRegistry registry) {}
/**
* Override this method to configure view resolution.
*/
protected void configureViewResolvers(ViewResolverRegistry registry) {}
/**
* Override this method to add custom HandlerMethodArgumentResolvers.
*/
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {}
/**
* Override this method to add custom HandlerMethodReturnValueHandlers.
*/
protected void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {}
/**
* Override this method to configure message converters.
*/
protected void configureMessageConverters(HttpMessageConverters.ServerBuilder builder) {}
/**
* Override this method to configure exception resolvers.
*/
protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {}
/**
* Override this method to extend the list of exception resolvers.
*/
protected void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {}
/**
* Override this method to provide a custom Validator.
*/
protected Validator getValidator() {
return null;
}
/**
* Override this method to provide a custom MessageCodesResolver.
*/
protected MessageCodesResolver getMessageCodesResolver() {
return null;
}
}Usage Example:
@Configuration
public class CustomWebMvcConfiguration extends WebMvcConfigurationSupport {
@Override
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping();
mapping.setOrder(0);
mapping.setRemoveSemicolonContent(false);
return mapping;
}
@Override
protected void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch(false);
}
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CustomInterceptor());
}
@Override
protected void configureMessageConverters(HttpMessageConverters.ServerBuilder builder) {
builder
.json()
.addConverter(new CustomConverter());
}
}Supporting classes used for configuration.
/**
* Assists with configuring HandlerMappings path matching options such as
* trailing slash match, suffix registration, path matcher and path helper.
*/
public class PathMatchConfigurer {
public PathMatchConfigurer setUseTrailingSlashMatch(Boolean trailingSlashMatch) {}
public PathMatchConfigurer setUrlPathHelper(UrlPathHelper urlPathHelper) {}
public PathMatchConfigurer setPathMatcher(PathMatcher pathMatcher) {}
public PathMatchConfigurer setPatternParser(PathPatternParser patternParser) {}
public PathMatchConfigurer addPathPrefix(String prefix, Predicate<Class<?>> predicate) {}
}
/**
* Creates a ContentNegotiationManager and configures it with one or more
* ContentNegotiationStrategy instances.
*/
public class ContentNegotiationConfigurer {
public ContentNegotiationConfigurer favorParameter(boolean favorParameter) {}
public ContentNegotiationConfigurer parameterName(String parameterName) {}
public ContentNegotiationConfigurer ignoreAcceptHeader(boolean ignoreAcceptHeader) {}
public ContentNegotiationConfigurer defaultContentType(MediaType... defaultContentTypes) {}
public ContentNegotiationConfigurer mediaType(String extension, MediaType mediaType) {}
public ContentNegotiationConfigurer mediaTypes(Map<String, MediaType> mediaTypes) {}
public ContentNegotiationConfigurer useRegisteredExtensionsOnly(boolean useOnly) {}
}
/**
* Assists with the configuration of API versioning for Spring MVC.
*
* @since 7.0
*/
public class ApiVersionConfigurer {
public ApiVersionConfigurer header(String headerName) {}
public ApiVersionConfigurer headerWithPrefix(String headerName, String prefix) {}
public ApiVersionConfigurer requestParam(String paramName) {}
public ApiVersionConfigurer pathVariable(String variableName) {}
public ApiVersionConfigurer mediaType(String parameterName, String prefix) {}
public ApiVersionConfigurer parser(Function<String, ApiVersion> parser) {}
}
/**
* Helps with configuring options for asynchronous request processing.
*/
public class AsyncSupportConfigurer {
public AsyncSupportConfigurer setTaskExecutor(AsyncTaskExecutor taskExecutor) {}
public AsyncSupportConfigurer setDefaultTimeout(long timeout) {}
public AsyncSupportConfigurer registerCallableInterceptors(CallableProcessingInterceptor... interceptors) {}
public AsyncSupportConfigurer registerDeferredResultInterceptors(DeferredResultProcessingInterceptor... interceptors) {}
}
/**
* Configures a request handler for serving static resources.
*/
public class DefaultServletHandlerConfigurer {
public void enable() {}
public void enable(String defaultServletName) {}
}
/**
* Assists with the registration of global, URL pattern based interceptors.
*/
public class InterceptorRegistry {
public InterceptorRegistration addInterceptor(HandlerInterceptor interceptor) {}
}
/**
* Encapsulates information required to create an interceptor for the mapped handler.
*/
public class InterceptorRegistration {
public InterceptorRegistration addPathPatterns(String... patterns) {}
public InterceptorRegistration excludePathPatterns(String... patterns) {}
public InterceptorRegistration pathMatcher(PathMatcher pathMatcher) {}
public InterceptorRegistration order(int order) {}
}
/**
* Stores registrations of resource handlers for serving static resources.
*/
public class ResourceHandlerRegistry {
public ResourceHandlerRegistration addResourceHandler(String... pathPatterns) {}
public boolean hasMappingForPattern(String pathPattern) {}
}
/**
* Encapsulates information required to create a resource handler.
*/
public class ResourceHandlerRegistration {
public ResourceHandlerRegistration addResourceLocations(String... locations) {}
public ResourceHandlerRegistration setCacheControl(CacheControl cacheControl) {}
public ResourceHandlerRegistration setCachePeriod(Integer cachePeriod) {}
public ResourceHandlerRegistration resourceChain(boolean cacheResources) {}
public ResourceChainRegistration resourceChain(boolean cacheResources, Cache cache) {}
}
/**
* Assists with the registration of resource resolvers and transformers.
*/
public class ResourceChainRegistration {
public ResourceChainRegistration addResolver(ResourceResolver resolver) {}
public ResourceChainRegistration addTransformer(ResourceTransformer transformer) {}
}
/**
* Assists with the registration of global CORS configuration mapped to a path pattern.
*/
public class CorsRegistry {
public CorsRegistration addMapping(String pathPattern) {}
}
/**
* Assists with the creation of a CorsConfiguration instance mapped to a path pattern.
*/
public class CorsRegistration {
public CorsRegistration allowedOrigins(String... origins) {}
public CorsRegistration allowedOriginPatterns(String... patterns) {}
public CorsRegistration allowedMethods(String... methods) {}
public CorsRegistration allowedHeaders(String... headers) {}
public CorsRegistration exposedHeaders(String... headers) {}
public CorsRegistration allowCredentials(boolean allowCredentials) {}
public CorsRegistration maxAge(long maxAge) {}
}
/**
* Assists with the registration of simple automated controllers pre-configured
* with status code and/or a view.
*/
public class ViewControllerRegistry {
public ViewControllerRegistration addViewController(String urlPath) {}
public RedirectViewControllerRegistration addRedirectViewController(String urlPath, String redirectUrl) {}
public void addStatusController(String urlPath, HttpStatus statusCode) {}
}
/**
* Assists with the registration of a single view controller.
*/
public class ViewControllerRegistration {
public void setViewName(String viewName) {}
public void setStatusCode(HttpStatus statusCode) {}
}
/**
* Assists with the configuration of a chain of ViewResolvers.
*/
public class ViewResolverRegistry {
public void enableContentNegotiation(View... defaultViews) {}
public void enableContentNegotiation(boolean useNotAcceptableStatus, View... defaultViews) {}
public UrlBasedViewResolverRegistration jsp() {}
public UrlBasedViewResolverRegistration jsp(String prefix, String suffix) {}
public void viewResolver(ViewResolver viewResolver) {}
public void order(int order) {}
}