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>
This commit is contained in:
Dmytro Nosan
2025-01-31 18:45:28 +02:00
committed by Stéphane Nicoll
parent 63ecfac40d
commit d27fd31a3d
3 changed files with 41 additions and 2 deletions

View File

@@ -76,6 +76,7 @@ import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.DefaultMessageCodesResolver;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
@@ -271,8 +272,12 @@ public class WebMvcAutoConfiguration {
if (contentnegotiation.getParameterName() != null) {
configurer.parameterName(contentnegotiation.getParameterName());
}
Map<String, MediaType> mediaTypes = this.mvcProperties.getContentnegotiation().getMediaTypes();
Map<String, MediaType> mediaTypes = contentnegotiation.getMediaTypes();
mediaTypes.forEach(configurer::mediaType);
List<MediaType> defaultContentTypes = contentnegotiation.getDefaultContentTypes();
if (!CollectionUtils.isEmpty(defaultContentTypes)) {
configurer.defaultContentType(defaultContentTypes.toArray(new MediaType[0]));
}
}
@Bean

View File

@@ -17,7 +17,9 @@
package org.springframework.boot.autoconfigure.web.servlet;
import java.time.Duration;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -317,6 +319,12 @@ public class WebMvcProperties {
*/
private String parameterName;
/**
* The default content types to be used when no specific content type is
* requested.
*/
private List<MediaType> defaultContentTypes = new ArrayList<>();
public boolean isFavorParameter() {
return this.favorParameter;
}
@@ -341,6 +349,14 @@ public class WebMvcProperties {
this.parameterName = parameterName;
}
public List<MediaType> getDefaultContentTypes() {
return this.defaultContentTypes;
}
public void setDefaultContentTypes(List<MediaType> defaultContentTypes) {
this.defaultContentTypes = defaultContentTypes;
}
}
public static class Pathmatch {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 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.
@@ -79,6 +79,7 @@ import org.springframework.format.Printer;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.util.ReflectionTestUtils;
@@ -86,6 +87,7 @@ import org.springframework.util.StringUtils;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.accept.FixedContentNegotiationStrategy;
import org.springframework.web.accept.ParameterContentNegotiationStrategy;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
@@ -577,6 +579,22 @@ class WebMvcAutoConfigurationTests {
});
}
@Test
void defaultContentTypes() {
this.contextRunner
.withPropertyValues("spring.mvc.contentnegotiation.default-content-types:application/json,application/xml")
.run((context) -> {
RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class);
ContentNegotiationManager contentNegotiationManager = (ContentNegotiationManager) ReflectionTestUtils
.getField(adapter, "contentNegotiationManager");
assertThat(contentNegotiationManager).isNotNull();
assertThat(contentNegotiationManager.getStrategy(FixedContentNegotiationStrategy.class))
.extracting(FixedContentNegotiationStrategy::getContentTypes)
.asInstanceOf(InstanceOfAssertFactories.list(MediaType.class))
.containsExactly(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML);
});
}
@Test
void formContentFilterIsAutoConfigured() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(OrderedFormContentFilter.class));