Relax media type checks in HttpMessageConverters

Prior to this commit, `HttpMessageConverters` would assert that the
given converter in `withXmlConverter` has a media type that is equal to
"application/xml" in its list of supported converters.

This approach would not work if the given converter supports
"application/xml;charset=UTF-8" because of the strict equal check being
performed.

This commit ensures that we only consider the type and subtype of the
considered media types when comparing, removing the parameters from the
picture.

Fixes gh-35801
This commit is contained in:
Brian Clozel
2025-11-12 15:50:15 +01:00
parent deca37da4a
commit 3ac7f83900
2 changed files with 26 additions and 18 deletions
@@ -162,8 +162,7 @@ class DefaultHttpMessageConverters implements HttpMessageConverters {
void setStringConverter(HttpMessageConverter<?> stringConverter) {
Assert.isTrue(stringConverter.getSupportedMediaTypes().contains(MediaType.TEXT_PLAIN),
"stringConverter should support 'text/plain'");
checkConverterSupports(stringConverter, MediaType.TEXT_PLAIN);
this.stringConverter = stringConverter;
}
@@ -173,20 +172,17 @@ class DefaultHttpMessageConverters implements HttpMessageConverters {
}
void setJsonConverter(HttpMessageConverter<?> jsonConverter) {
Assert.isTrue(jsonConverter.getSupportedMediaTypes().contains(MediaType.APPLICATION_JSON),
"jsonConverter should support 'application/json'");
checkConverterSupports(jsonConverter, MediaType.APPLICATION_JSON);
this.jsonConverter = jsonConverter;
}
void setXmlConverter(HttpMessageConverter<?> xmlConverter) {
Assert.isTrue(xmlConverter.getSupportedMediaTypes().contains(MediaType.TEXT_XML),
"xmlConverter should support 'text/xml'");
checkConverterSupports(xmlConverter, MediaType.TEXT_XML);
this.xmlConverter = xmlConverter;
}
void setSmileConverter(HttpMessageConverter<?> smileConverter) {
Assert.isTrue(smileConverter.getSupportedMediaTypes().contains(new MediaType("application", "x-jackson-smile")),
"smileConverter should support 'application/x-jackson-smile'");
checkConverterSupports(smileConverter, new MediaType("application", "x-jackson-smile"));
this.smileConverter = smileConverter;
}
@@ -196,17 +192,24 @@ class DefaultHttpMessageConverters implements HttpMessageConverters {
}
void setCborConverter(HttpMessageConverter<?> cborConverter) {
Assert.isTrue(cborConverter.getSupportedMediaTypes().contains(MediaType.APPLICATION_CBOR),
"cborConverter should support 'application/cbor'");
checkConverterSupports(cborConverter, MediaType.APPLICATION_CBOR);
this.cborConverter = cborConverter;
}
void setYamlConverter(HttpMessageConverter<?> yamlConverter) {
Assert.isTrue(yamlConverter.getSupportedMediaTypes().contains(MediaType.APPLICATION_YAML),
"yamlConverter should support 'application/yaml'");
checkConverterSupports(yamlConverter, MediaType.APPLICATION_YAML);
this.yamlConverter = yamlConverter;
}
private void checkConverterSupports(HttpMessageConverter<?> converter, MediaType mediaType) {
for (MediaType supportedMediaType : converter.getSupportedMediaTypes()) {
if (mediaType.equalsTypeAndSubtype(supportedMediaType)) {
return;
}
}
throw new IllegalArgumentException("converter should support '" + mediaType + "'");
}
void addCustomMessageConverter(HttpMessageConverter<?> customConverter) {
Assert.notNull(customConverter, "'customConverter' must not be null");
this.customConverters.add(customConverter);