0
# Configuration Framework
1
2
Spring MVC's configuration framework provides a Java-based configuration system using the @EnableWebMvc annotation and WebMvcConfigurer interface. This allows for programmatic customization of Spring MVC behavior without XML configuration files.
3
4
## Capabilities
5
6
### @EnableWebMvc
7
8
Main annotation that enables Spring MVC configuration by importing DelegatingWebMvcConfiguration, which provides all the necessary infrastructure beans.
9
10
```java { .api }
11
/**
12
* Add this annotation to an @Configuration class to enable Spring MVC configuration.
13
* Imports all necessary MVC infrastructure beans.
14
*/
15
@Retention(RetentionPolicy.RUNTIME)
16
@Target(ElementType.TYPE)
17
@Documented
18
@Import(DelegatingWebMvcConfiguration.class)
19
public @interface EnableWebMvc {
20
// No parameters - simply enables MVC configuration
21
}
22
```
23
24
**Usage Example:**
25
26
```java
27
@Configuration
28
@EnableWebMvc
29
@ComponentScan(basePackages = "com.example.controllers")
30
public class WebMvcConfig implements WebMvcConfigurer {
31
32
// WebMvcConfigurer methods for customization
33
34
@Bean
35
public ViewResolver viewResolver() {
36
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
37
resolver.setPrefix("/WEB-INF/views/");
38
resolver.setSuffix(".jsp");
39
return resolver;
40
}
41
}
42
```
43
44
### WebMvcConfigurer
45
46
Central interface for customizing Spring MVC configuration. Provides callback methods that are invoked during the configuration process, allowing you to add interceptors, configure view resolvers, set up resource handlers, and more.
47
48
```java { .api }
49
/**
50
* Defines callback methods to customize the Java-based configuration for Spring MVC.
51
* All methods have empty default implementations.
52
*/
53
public interface WebMvcConfigurer {
54
55
/** Configure path matching options */
56
default void configurePathMatch(PathMatchConfigurer configurer) {}
57
58
/** Configure content negotiation options */
59
default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}
60
61
/** Configure asynchronous request processing options */
62
default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}
63
64
/** Configure default servlet handling for static resource requests */
65
default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}
66
67
/** Add custom Formatter and Converter implementations */
68
default void addFormatters(FormatterRegistry registry) {}
69
70
/** Add HandlerInterceptors for pre- and post-processing */
71
default void addInterceptors(InterceptorRegistry registry) {}
72
73
/** Add handlers for serving static resources */
74
default void addResourceHandlers(ResourceHandlerRegistry registry) {}
75
76
/** Configure Cross-Origin Resource Sharing (CORS) mappings */
77
default void addCorsMappings(CorsRegistry registry) {}
78
79
/** Configure simple automated controllers for view names */
80
default void addViewControllers(ViewControllerRegistry registry) {}
81
82
/** Configure view resolvers */
83
default void configureViewResolvers(ViewResolverRegistry registry) {}
84
85
/** Add custom HandlerMethodArgumentResolver implementations */
86
default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {}
87
88
/** Add custom HandlerMethodReturnValueHandler implementations */
89
default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {}
90
91
/** Configure or replace the list of HttpMessageConverter instances */
92
default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}
93
94
/** Extend the list of HttpMessageConverter instances */
95
default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}
96
97
/** Configure exception handling */
98
default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}
99
100
/** Extend exception handling */
101
default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}
102
103
/** Provide a custom Validator instance */
104
default Validator getValidator() { return null; }
105
106
/** Provide a custom MessageCodesResolver for building message codes */
107
default MessageCodesResolver getMessageCodesResolver() { return null; }
108
}
109
```
110
111
**Complete Usage Example:**
112
113
```java
114
@Configuration
115
@EnableWebMvc
116
@ComponentScan(basePackages = "com.example")
117
public class WebConfig implements WebMvcConfigurer {
118
119
@Override
120
public void configurePathMatch(PathMatchConfigurer configurer) {
121
configurer.setUseTrailingSlashMatch(false);
122
configurer.setUseSuffixPatternMatch(false);
123
}
124
125
@Override
126
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
127
configurer.defaultContentType(MediaType.APPLICATION_JSON);
128
configurer.favorParameter(false);
129
configurer.favorPathExtension(false);
130
}
131
132
@Override
133
public void addInterceptors(InterceptorRegistry registry) {
134
registry.addInterceptor(new LoggingInterceptor())
135
.addPathPatterns("/api/**")
136
.excludePathPatterns("/api/public/**");
137
}
138
139
@Override
140
public void addResourceHandlers(ResourceHandlerRegistry registry) {
141
registry.addResourceHandler("/static/**")
142
.addResourceLocations("classpath:/static/")
143
.setCachePeriod(3600);
144
}
145
146
@Override
147
public void addCorsMappings(CorsRegistry registry) {
148
registry.addMapping("/api/**")
149
.allowedOrigins("http://localhost:3000")
150
.allowedMethods("GET", "POST", "PUT", "DELETE")
151
.allowCredentials(true);
152
}
153
154
@Override
155
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
156
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
157
.indentOutput(true)
158
.dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
159
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
160
}
161
}
162
```
163
164
### WebMvcConfigurationSupport
165
166
The main class that provides the configuration behind @EnableWebMvc. Can be extended directly for advanced customization scenarios where WebMvcConfigurer is insufficient.
167
168
```java { .api }
169
/**
170
* This is the main class providing the configuration behind the MVC Java config.
171
* Extend this class when WebMvcConfigurer callbacks are insufficient.
172
*/
173
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
174
175
/** Create RequestMappingHandlerMapping for @RequestMapping processing */
176
@Bean
177
public RequestMappingHandlerMapping requestMappingHandlerMapping();
178
179
/** Create RequestMappingHandlerAdapter for @RequestMapping processing */
180
@Bean
181
public RequestMappingHandlerAdapter requestMappingHandlerAdapter();
182
183
/** Create HandlerExceptionResolver chain */
184
@Bean
185
public HandlerExceptionResolver handlerExceptionResolver();
186
187
/** Configure path matching options - override for customization */
188
protected void configurePathMatch(PathMatchConfigurer configurer) {}
189
190
/** Configure content negotiation - override for customization */
191
protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}
192
193
/** Add custom interceptors - override for customization */
194
protected void addInterceptors(InterceptorRegistry registry) {}
195
196
/** Add resource handlers - override for customization */
197
protected void addResourceHandlers(ResourceHandlerRegistry registry) {}
198
}
199
```
200
201
## Registry Classes
202
203
### ResourceHandlerRegistry
204
205
Stores registrations of resource handlers for serving static resources like CSS, JavaScript, images, etc.
206
207
```java { .api }
208
/**
209
* Stores registrations of resource handlers for serving static resources.
210
*/
211
public class ResourceHandlerRegistry {
212
213
/**
214
* Add a resource handler for serving static resources based on URL patterns.
215
* Returns ResourceHandlerRegistration for further configuration.
216
*/
217
public ResourceHandlerRegistration addResourceHandler(String... pathPatterns);
218
219
/** Check if a resource handler is registered for the given path pattern */
220
public boolean hasMappingForPattern(String pathPattern);
221
222
/** Get the order value for resource handlers */
223
public int getOrder();
224
}
225
226
/**
227
* Configuration for a single resource handler registration.
228
*/
229
public class ResourceHandlerRegistration {
230
231
/** Add resource locations to serve resources from */
232
public ResourceHandlerRegistration addResourceLocations(String... resourceLocations);
233
234
/** Set cache period in seconds for the resources */
235
public ResourceHandlerRegistration setCachePeriod(Integer cachePeriod);
236
237
/** Configure HTTP caching with CacheControl directives */
238
public ResourceHandlerRegistration setCacheControl(CacheControl cacheControl);
239
240
/** Add resource resolvers for custom resource resolution */
241
public ResourceHandlerRegistration resourceChain(boolean cacheResources);
242
243
/** Configure resource transformation */
244
public ResourceChainRegistration resourceChain(boolean cacheResources, Cache cache);
245
}
246
```
247
248
**Usage Example:**
249
250
```java
251
@Override
252
public void addResourceHandlers(ResourceHandlerRegistry registry) {
253
// Serve static assets
254
registry.addResourceHandler("/assets/**")
255
.addResourceLocations("classpath:/static/assets/")
256
.setCachePeriod(3600)
257
.resourceChain(true)
258
.addResolver(new PathResourceResolver());
259
260
// Serve uploaded files
261
registry.addResourceHandler("/uploads/**")
262
.addResourceLocations("file:/var/app/uploads/")
263
.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS));
264
}
265
```
266
267
### InterceptorRegistry
268
269
Registry for configuring HandlerInterceptor instances that will be applied to incoming requests.
270
271
```java { .api }
272
/**
273
* Helps with configuring a list of mapped interceptors.
274
*/
275
public class InterceptorRegistry {
276
277
/**
278
* Add an interceptor and return InterceptorRegistration for further configuration.
279
*/
280
public InterceptorRegistration addInterceptor(HandlerInterceptor interceptor);
281
282
/** Get the list of configured interceptors and their mappings */
283
public List<Object> getInterceptors();
284
}
285
286
/**
287
* Configuration for a single interceptor registration.
288
*/
289
public class InterceptorRegistration {
290
291
/** Add path patterns to include for this interceptor */
292
public InterceptorRegistration addPathPatterns(String... pathPatterns);
293
294
/** Add path patterns to exclude for this interceptor */
295
public InterceptorRegistration excludePathPatterns(String... pathPatterns);
296
297
/** Set order for this interceptor relative to others */
298
public InterceptorRegistration order(int order);
299
}
300
```
301
302
**Usage Example:**
303
304
```java
305
@Override
306
public void addInterceptors(InterceptorRegistry registry) {
307
// Security interceptor for admin pages
308
registry.addInterceptor(new SecurityInterceptor())
309
.addPathPatterns("/admin/**")
310
.excludePathPatterns("/admin/login")
311
.order(1);
312
313
// Logging interceptor for all API calls
314
registry.addInterceptor(new LoggingInterceptor())
315
.addPathPatterns("/api/**")
316
.order(2);
317
}
318
```
319
320
### ViewControllerRegistry
321
322
Registry for configuring simple automated controllers that pre-populate the model or just forward to a view.
323
324
```java { .api }
325
/**
326
* Assists with the registration of simple automated controllers pre-configured with status code and/or view.
327
*/
328
public class ViewControllerRegistry {
329
330
/** Add a view controller that renders a view */
331
public ViewControllerRegistration addViewController(String urlPath);
332
333
/** Add a redirect view controller */
334
public RedirectViewControllerRegistration addRedirectViewController(String urlPath, String redirectUrl);
335
336
/** Add a status controller that sets a specific HTTP status */
337
public void addStatusController(String urlPath, HttpStatusCode statusCode);
338
}
339
340
/**
341
* Configuration for a view controller registration.
342
*/
343
public class ViewControllerRegistration {
344
345
/** Set the view name to render */
346
public void setViewName(String viewName);
347
348
/** Set the HTTP status code */
349
public void setStatusCode(HttpStatusCode statusCode);
350
}
351
```
352
353
**Usage Example:**
354
355
```java
356
@Override
357
public void addViewControllers(ViewControllerRegistry registry) {
358
// Simple page redirects
359
registry.addViewController("/").setViewName("home");
360
registry.addViewController("/login").setViewName("login");
361
362
// Redirect controllers
363
registry.addRedirectViewController("/home", "/");
364
365
// Status controllers
366
registry.addStatusController("/health", HttpStatus.OK);
367
}
368
```
369
370
### CorsRegistry
371
372
Registry for configuring Cross-Origin Resource Sharing (CORS) mappings.
373
374
```java { .api }
375
/**
376
* Assists with the registration of global, URL pattern based CorsConfiguration mappings.
377
*/
378
public class CorsRegistry {
379
380
/**
381
* Enable CORS for the specified path pattern.
382
* Returns CorsRegistration for further configuration.
383
*/
384
public CorsRegistration addMapping(String pathPattern);
385
}
386
387
/**
388
* Configuration for a CORS mapping registration.
389
*/
390
public class CorsRegistration {
391
392
/** Set allowed origins (default: all origins) */
393
public CorsRegistration allowedOrigins(String... origins);
394
395
/** Set allowed origin patterns for more flexible matching */
396
public CorsRegistration allowedOriginPatterns(String... originPatterns);
397
398
/** Set allowed HTTP methods (default: GET, HEAD, POST) */
399
public CorsRegistration allowedMethods(String... methods);
400
401
/** Set allowed request headers (default: all headers) */
402
public CorsRegistration allowedHeaders(String... headers);
403
404
/** Set exposed response headers */
405
public CorsRegistration exposedHeaders(String... headers);
406
407
/** Set whether credentials are allowed (default: false) */
408
public CorsRegistration allowCredentials(boolean allowCredentials);
409
410
/** Set max age for preflight responses in seconds (default: 1800) */
411
public CorsRegistration maxAge(long maxAge);
412
}
413
```
414
415
**Usage Example:**
416
417
```java
418
@Override
419
public void addCorsMappings(CorsRegistry registry) {
420
// Allow specific origins for API endpoints
421
registry.addMapping("/api/**")
422
.allowedOrigins("http://localhost:3000", "https://myapp.com")
423
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
424
.allowedHeaders("*")
425
.allowCredentials(true)
426
.maxAge(3600);
427
428
// More restrictive for admin endpoints
429
registry.addMapping("/admin/api/**")
430
.allowedOrigins("https://admin.myapp.com")
431
.allowedMethods("GET", "POST")
432
.allowCredentials(true);
433
}
434
```
435
436
## Configurers
437
438
### PathMatchConfigurer
439
440
Configures path matching options for URL patterns.
441
442
```java { .api }
443
/**
444
* Helps with configuring options for path matching.
445
*/
446
public class PathMatchConfigurer {
447
448
/** Enable/disable suffix pattern matching (deprecated, default: false) */
449
public PathMatchConfigurer setUseSuffixPatternMatch(boolean useSuffixPatternMatch);
450
451
/** Enable/disable registered suffix pattern matching (deprecated) */
452
public PathMatchConfigurer setUseRegisteredSuffixPatternMatch(boolean useRegisteredSuffixPatternMatch);
453
454
/** Enable/disable trailing slash matching (default: true) */
455
public PathMatchConfigurer setUseTrailingSlashMatch(boolean useTrailingSlashMatch);
456
457
/** Set custom PathMatcher implementation */
458
public PathMatchConfigurer setPathMatcher(PathMatcher pathMatcher);
459
460
/** Set custom UrlPathHelper implementation */
461
public PathMatchConfigurer setUrlPathHelper(UrlPathHelper urlPathHelper);
462
}
463
```
464
465
### ContentNegotiationConfigurer
466
467
Configures content negotiation options for determining the requested media types.
468
469
```java { .api }
470
/**
471
* Creates a ContentNegotiationManager and configures it with one or more ContentNegotiationStrategy instances.
472
*/
473
public class ContentNegotiationConfigurer {
474
475
/** Enable/disable favor of path extension for content negotiation */
476
public ContentNegotiationConfigurer favorPathExtension(boolean favorPathExtension);
477
478
/** Enable/disable favor of parameter for content negotiation */
479
public ContentNegotiationConfigurer favorParameter(boolean favorParameter);
480
481
/** Set parameter name for content negotiation (default: format) */
482
public ContentNegotiationConfigurer parameterName(String parameterName);
483
484
/** Ignore Accept header for content negotiation */
485
public ContentNegotiationConfigurer ignoreAcceptHeader(boolean ignoreAcceptHeader);
486
487
/** Set default content type */
488
public ContentNegotiationConfigurer defaultContentType(MediaType... defaultContentTypes);
489
490
/** Add media type mappings for file extensions */
491
public ContentNegotiationConfigurer mediaType(String extension, MediaType mediaType);
492
493
/** Replace all media type mappings */
494
public ContentNegotiationConfigurer mediaTypes(Map<String, MediaType> mediaTypes);
495
}
496
```
497
498
**Complete Configuration Example:**
499
500
```java
501
@Configuration
502
@EnableWebMvc
503
public class AdvancedWebConfig implements WebMvcConfigurer {
504
505
@Override
506
public void configurePathMatch(PathMatchConfigurer configurer) {
507
configurer.setUseTrailingSlashMatch(false)
508
.setUseSuffixPatternMatch(false)
509
.setPathMatcher(new AntPathMatcher())
510
.setUrlPathHelper(new UrlPathHelper());
511
}
512
513
@Override
514
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
515
configurer.favorPathExtension(false)
516
.favorParameter(true)
517
.parameterName("mediaType")
518
.ignoreAcceptHeader(false)
519
.defaultContentType(MediaType.APPLICATION_JSON)
520
.mediaType("json", MediaType.APPLICATION_JSON)
521
.mediaType("xml", MediaType.APPLICATION_XML);
522
}
523
524
@Override
525
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
526
configurer.setDefaultTimeout(30000)
527
.setTaskExecutor(new SimpleAsyncTaskExecutor());
528
}
529
}
530
```