Understanding WebMvcConfigurationSupport in Spring Framework

WebMvcConfigurationSupport serves as the core configuration mechanism for Spring's web MVC functionality in version 5.x. For Spring 6.x applications, developers should implement WebMvcConfigurer instead (preferably with @EnableWebMvc annotation).

This configuration class handles the fundamental setup required for Spring MVC operations. Understanding its role and functionality is crucial for Spring web development.

The abbreviation "WCS" will be used throughout this discussion to refer to WebMvcConfigurationSupport.

This analysis focuses on components related to DispatcherServlet and WCS interactions, excluding container-level HTTP request mechanisms.

After reading this article, you will:

  • Understand what WCS accomplishes
  • Learn how to utilize WCS effectively
  • Gain reference material for WCS implementation

WCS Overview

Original Documentation Summary

WCS provides the primary configuration infrastructure for MVC Java-based configurations. It's typically imported by adding @EnableWebMvc to a @Configuration class. Alternatively, developers can extend this class directly and override methods as needed, ensuring the subclass includes @Configuration annotation and @Bean annotations on overridden methods.

This class registers several key components:

Handler Mappings:

  • RequestMappingHandlerMapping at order 0 for annotated controller method mapping
  • HandlerMapping at order 1 for direct URL-to-view-name mapping
  • BeanNameUrlHandlerMapping at order 2 for URL-to-controller-bean-name mapping
  • RouterFunctionMapping at order 3 for router function mapping
  • HandlerMapping at Integer.MAX_VALUE-1 for static resource requests
  • HandlerMapping at Integer.MAX_VALUE for default servlet forwarding

Handler Adapters:

  • RequestMappingHandlerAdapter for annotated controller method processing
  • HttpRequestHandlerAdapter for HttpRequestHandler processing
  • SimpleControllerHandlerAdapter for interface-based controller processing
  • HandlerFunctionAdapter for router function processing

Exception Resolvers:

  • ExceptionHandlerExceptionResolver for @ExceptionHandler method handling
  • ResponseStatusExceptionResolver for @ResponseStatus annotated exceptions
  • DefaultHandlerExceptionResolver for standard Spring exception types

Core Functionality

WCS manages various web MVC configurations by defining numerous beans (approximately 25) that enable different MVC pipeline stages to retrieve and utilize these components for web MVC operations.

Key responsibilities include:

  • Registering handler mappings to route requests to controllers, methods, views, and resources
  • Registering handler adapters for specific processing tasks like parameter parsing and message conversion
  • Registering exception handlers
  • Registering path matching utilities

Essentially, WCS provides Spring with tools for handling request processing, mapping relationships, parameter parsing, and response messaging.

Key Terminology

Resolvers

English: Resolver
Refers to problem-solving components that handle different scenarios based on context.

Interceptors

English: Interceptor
Components that intercept HTTP requests, similar to filters but capable of interrupting request flow.

Controllers, Parameters, Methods

Controllers correspond to @Controller annotations, parameters represent method inputs, and methods refer to request-handling controller methods.

Return Values and Messages

Return values are controller method outputs, while messages encompass client requests and server responses, particularly concerning @ResponseBody annotations.

CORS

Cross-origin resource sharing enables controlled access to resources from different origins.

Resources and Views

Resources represent static data (images, scripts, text), while views represent display pages.

Validators

Components for validating specific parameters using simple business logic.

Formatters and Converters

Components for transforming and formatting data, including message and property conversions.

Application Context and Servlet Context

ApplicationContext: Spring's applicaiton context managing beans
ServletContext: Web server/container context containing application-wide information

Media Types

MediaType represents content type information, extending MimeType with additional Spring-specific functionality.

RequestMappingHandlerMapping

Handles RequestMapping annotation processing and establishes mapping relationships between annotations and resources:

@Bean
@SuppressWarnings("deprecation")
public RequestMappingHandlerMapping requestMappingHandlerMapping(
        @Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
        @Qualifier("mvcConversionService") FormattingConversionService conversionService,
        @Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {

    RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
    mapping.setOrder(0);
    mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
    mapping.setContentNegotiationManager(contentNegotiationManager);
    mapping.setCorsConfigurations(getCorsConfigurations());

    PathMatchConfigurer pathConfig = getPathMatchConfigurer();
    if (pathConfig.getPatternParser() != null) {
        mapping.setPatternParser(pathConfig.getPatternParser());
    } else {
        mapping.setUrlPathHelper(pathConfig.getUrlPathHelperOrDefault());
        mapping.setPathMatcher(pathConfig.getPathMatcherOrDefault());

        Boolean useSuffixPatternMatch = pathConfig.isUseSuffixPatternMatch();
        if (useSuffixPatternMatch != null) {
            mapping.setUseSuffixPatternMatch(useSuffixPatternMatch);
        }
        Boolean useRegisteredSuffixPatternMatch = pathConfig.isUseRegisteredSuffixPatternMatch();
        if (useRegisteredSuffixPatternMatch != null) {
            mapping.setUseRegisteredSuffixPatternMatch(useRegisteredSuffixPatternMatch);
        }
    }
    Boolean useTrailingSlashMatch = pathConfig.isUseTrailingSlashMatch();
    if (useTrailingSlashMatch != null) {
        mapping.setUseTrailingSlashMatch(useTrailingSlashMatch);
    }
    if (pathConfig.getPathPrefixes() != null) {
        mapping.setPathPrefixes(pathConfig.getPathPrefixes());
    }

    return mapping;
}

This creates a handler mapping containing interceptors, content negotiation managers, CORS configurations, and path matching utilities.

RequestMappingHandlerAdapter

Processes RequestMapping annotated controller methods:

@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
        @Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
        @Qualifier("mvcConversionService") FormattingConversionService conversionService,
        @Qualifier("mvcValidator") Validator validator) {
    
    RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
    adapter.setContentNegotiationManager(contentNegotiationManager);
    adapter.setMessageConverters(getMessageConverters());
    adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(conversionService, validator));
    adapter.setCustomArgumentResolvers(getArgumentResolvers());
    adapter.setCustomReturnValueHandlers(getReturnValueHandlers());

    if (jackson2Present) {
        adapter.setRequestBodyAdvice(Collections.singletonList(new JsonViewRequestBodyAdvice()));
        adapter.setResponseBodyAdvice(Collections.singletonList(new JsonViewResponseBodyAdvice()));
    }

    AsyncSupportConfigurer configurer = getAsyncSupportConfigurer();
    if (configurer.getTaskExecutor() != null) {
        adapter.setTaskExecutor(configurer.getTaskExecutor());
    }
    if (configurer.getTimeout() != null) {
        adapter.setAsyncRequestTimeout(configurer.getTimeout());
    }
    adapter.setCallableInterceptors(configurer.getCallableInterceptors());
    adapter.setDeferredResultInterceptors(configurer.getDeferredResultInterceptors());

    return adapter;
}

Key features include media type management, message conversion, web binding initialization, custom argument resolvers, and asynchronous support.

HTTP Request Processing Flow

Spring MVC processes HTTP requests through various components managed by DispatcherServlet, which maintains properties including multipart resolvers, locale resolvers, handler mappings, handler adapters, and view resolvers.

Common Configuration: Interceptors

Interceptor configuration example:

@Override
protected void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new CustomAuthenticationInterceptor())
            .addPathPatterns("/**")
            .excludePathPatterns("*.js", "*.html", "*.css")
            .excludePathPatterns("/public/**", "/health");
    super.addInterceptors(registry);
}

Common Configuration: Custom Parameter Resolution

Spring allows custom parameter resolution beyond built-in annotations like @RequestBody and @RequestParam.

Custom Parameter Annotation Example

Define a custom annotation:

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}

public class UserArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(CurrentUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        return request.getSession().getAttribute("currentUser");
    }
}

// Register in WCS
@Override
public void addArgumentResolvers(List<handlermethodargumentresolver> resolvers) {
    resolvers.add(new UserArgumentResolver());
}

// Usage in controller
@RequestMapping("/process")
@ResponseBody
public ResponseData process(@CurrentUser UserInfo currentUser) {
    // Process with current user info
    return new ResponseData();
}
</handlermethodargumentresolver>

Response Message Configuration

Multiple HTTP message converters can handle different media types by implementing HttpMessageConverter interface.

Jackson configuration example:

@Override
protected void configureMessageConverters(List<httpmessageconverter>> converters) {
    converters.add(new ByteArrayHttpMessageConverter());
    converters.add(new StringHttpMessageConverter());
    converters.add(new ResourceHttpMessageConverter());
    
    MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
    ObjectMapper mapper = jacksonConverter.getObjectMapper();
    
    // Configure null serialization
    mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<object>() {
        @Override
        public void serialize(Object obj, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeString("");
        }
    });
    
    // Set date format
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    mapper.setDateFormat(dateFormat);
    
    converters.add(jacksonConverter);
}
</object></httpmessageconverter>

View and Resource Configuration

Resource and view configuration examples:

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/static/**")
            .addResourceLocations("classpath:/static/")
            .addResourceLocations("file:" + uploadDirectory);
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("home/index");
    registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    super.addViewControllers(registry);
}

Tags: spring-framework webmvc configuration mvc request-mapping

Posted on Sun, 17 May 2026 12:41:47 +0000 by xgrewellx