Skip to content

Commit d27fd31

Browse files
nosansnicoll
authored andcommitted
Add property to configure Spring MVC default content types
This commit adds a configuration property to configure the default content types with Spring MVC. See gh-44040 Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
1 parent 63ecfac commit d27fd31

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import org.springframework.http.converter.HttpMessageConverter;
7777
import org.springframework.util.AntPathMatcher;
7878
import org.springframework.util.ClassUtils;
79+
import org.springframework.util.CollectionUtils;
7980
import org.springframework.validation.DefaultMessageCodesResolver;
8081
import org.springframework.validation.MessageCodesResolver;
8182
import org.springframework.validation.Validator;
@@ -271,8 +272,12 @@ public void configureContentNegotiation(ContentNegotiationConfigurer configurer)
271272
if (contentnegotiation.getParameterName() != null) {
272273
configurer.parameterName(contentnegotiation.getParameterName());
273274
}
274-
Map<String, MediaType> mediaTypes = this.mvcProperties.getContentnegotiation().getMediaTypes();
275+
Map<String, MediaType> mediaTypes = contentnegotiation.getMediaTypes();
275276
mediaTypes.forEach(configurer::mediaType);
277+
List<MediaType> defaultContentTypes = contentnegotiation.getDefaultContentTypes();
278+
if (!CollectionUtils.isEmpty(defaultContentTypes)) {
279+
configurer.defaultContentType(defaultContentTypes.toArray(new MediaType[0]));
280+
}
276281
}
277282

278283
@Bean

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcProperties.java

+16
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
package org.springframework.boot.autoconfigure.web.servlet;
1818

1919
import java.time.Duration;
20+
import java.util.ArrayList;
2021
import java.util.LinkedHashMap;
22+
import java.util.List;
2123
import java.util.Map;
2224

2325
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -317,6 +319,12 @@ public static class Contentnegotiation {
317319
*/
318320
private String parameterName;
319321

322+
/**
323+
* The default content types to be used when no specific content type is
324+
* requested.
325+
*/
326+
private List<MediaType> defaultContentTypes = new ArrayList<>();
327+
320328
public boolean isFavorParameter() {
321329
return this.favorParameter;
322330
}
@@ -341,6 +349,14 @@ public void setParameterName(String parameterName) {
341349
this.parameterName = parameterName;
342350
}
343351

352+
public List<MediaType> getDefaultContentTypes() {
353+
return this.defaultContentTypes;
354+
}
355+
356+
public void setDefaultContentTypes(List<MediaType> defaultContentTypes) {
357+
this.defaultContentTypes = defaultContentTypes;
358+
}
359+
344360
}
345361

346362
public static class Pathmatch {

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,13 +79,15 @@
7979
import org.springframework.format.support.FormattingConversionService;
8080
import org.springframework.http.CacheControl;
8181
import org.springframework.http.HttpHeaders;
82+
import org.springframework.http.MediaType;
8283
import org.springframework.http.converter.HttpMessageConverter;
8384
import org.springframework.mock.web.MockHttpServletRequest;
8485
import org.springframework.test.util.ReflectionTestUtils;
8586
import org.springframework.util.StringUtils;
8687
import org.springframework.validation.Validator;
8788
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
8889
import org.springframework.web.accept.ContentNegotiationManager;
90+
import org.springframework.web.accept.FixedContentNegotiationStrategy;
8991
import org.springframework.web.accept.ParameterContentNegotiationStrategy;
9092
import org.springframework.web.bind.annotation.ControllerAdvice;
9193
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
@@ -577,6 +579,22 @@ void customMediaTypes() {
577579
});
578580
}
579581

582+
@Test
583+
void defaultContentTypes() {
584+
this.contextRunner
585+
.withPropertyValues("spring.mvc.contentnegotiation.default-content-types:application/json,application/xml")
586+
.run((context) -> {
587+
RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class);
588+
ContentNegotiationManager contentNegotiationManager = (ContentNegotiationManager) ReflectionTestUtils
589+
.getField(adapter, "contentNegotiationManager");
590+
assertThat(contentNegotiationManager).isNotNull();
591+
assertThat(contentNegotiationManager.getStrategy(FixedContentNegotiationStrategy.class))
592+
.extracting(FixedContentNegotiationStrategy::getContentTypes)
593+
.asInstanceOf(InstanceOfAssertFactories.list(MediaType.class))
594+
.containsExactly(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML);
595+
});
596+
}
597+
580598
@Test
581599
void formContentFilterIsAutoConfigured() {
582600
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(OrderedFormContentFilter.class));

0 commit comments

Comments
 (0)