Skip to content

Commit

Permalink
Merge pull request #44040 from nosan
Browse files Browse the repository at this point in the history
* pr/44040:
  Polish "Add property to configure Spring MVC default content types"
  Add property to configure Spring MVC default content types

Closes gh-44040
  • Loading branch information
snicoll committed Feb 4, 2025
2 parents 63ecfac + e5b0386 commit 3b8148e
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
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;
Expand Down Expand Up @@ -271,8 +272,12 @@ public void configureContentNegotiation(ContentNegotiationConfigurer configurer)
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -306,16 +308,22 @@ public static class Contentnegotiation {
*/
private boolean favorParameter = false;

/**
* Query parameter name to use when "favor-parameter" is enabled.
*/
private String parameterName;

/**
* Map file extensions to media types for content negotiation. For instance, yml
* to text/yaml.
*/
private Map<String, MediaType> mediaTypes = new LinkedHashMap<>();

/**
* Query parameter name to use when "favor-parameter" is enabled.
* List of default content types to be used when no specific content type is
* requested.
*/
private String parameterName;
private List<MediaType> defaultContentTypes = new ArrayList<>();

public boolean isFavorParameter() {
return this.favorParameter;
Expand All @@ -325,6 +333,14 @@ public void setFavorParameter(boolean favorParameter) {
this.favorParameter = favorParameter;
}

public String getParameterName() {
return this.parameterName;
}

public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}

public Map<String, MediaType> getMediaTypes() {
return this.mediaTypes;
}
Expand All @@ -333,12 +349,12 @@ public void setMediaTypes(Map<String, MediaType> mediaTypes) {
this.mediaTypes = mediaTypes;
}

public String getParameterName() {
return this.parameterName;
public List<MediaType> getDefaultContentTypes() {
return this.defaultContentTypes;
}

public void setParameterName(String parameterName) {
this.parameterName = parameterName;
public void setDefaultContentTypes(List<MediaType> defaultContentTypes) {
this.defaultContentTypes = defaultContentTypes;
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -79,13 +79,15 @@
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;
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;
Expand Down Expand Up @@ -577,6 +579,22 @@ void customMediaTypes() {
});
}

@Test
void customDefaultContentTypes() {
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));
Expand Down

0 comments on commit 3b8148e

Please sign in to comment.