Use Content-Type charset in JAXB message converters

Prior to this commit, the JAXB message converters would only rely on the
encoding declaration inside the XML document for reading the document.
This would then use the default UTF-8 encoding, even if the HTTP message
has the `"application/xml;charset=iso-8859-1"` Content-Type.

This commit ensures that both `Jaxb2CollectionHttpMessageConverter` and
`Jaxb2RootElementHttpMessageConverter` use the encoding declared in the
HTTP Content-Type, if present.

Fixes gh-34745
This commit is contained in:
Brian Clozel
2025-05-19 16:57:57 +02:00
parent fdab8fabd2
commit 2af0323c21
5 changed files with 56 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-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.
@@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.lang.Nullable;
import org.springframework.web.testfixture.http.MockHttpInputMessage;
@@ -204,6 +205,18 @@ class Jaxb2CollectionHttpMessageConverterTests {
.withMessageContaining("\"lol9\"");
}
@Test
@SuppressWarnings("unchecked")
public void readXmlRootElementListHeaderCharset() throws Exception {
String content = "<list><rootElement><type s=\"Hellø Wørld\"/></rootElement></list>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes(StandardCharsets.ISO_8859_1));
inputMessage.getHeaders().setContentType(MediaType.parseMediaType("application/xml;charset=iso-8859-1"));
List<RootElement> result = (List<RootElement>) converter.read(rootElementListType, null, inputMessage);
assertThat(result).as("Invalid result").hasSize(1);
assertThat(result.get(0).type.s).as("Invalid result").isEqualTo("Hellø Wørld");
}
@XmlRootElement
public static class RootElement {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-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.
@@ -180,6 +180,15 @@ class Jaxb2RootElementHttpMessageConverterTests {
.withMessageContaining("DOCTYPE");
}
@Test
void readXmlRootElementHeaderCharset() throws Exception {
byte[] body = "<rootElement><type s=\"Hellø Wørld\"/></rootElement>".getBytes(StandardCharsets.ISO_8859_1);
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body);
inputMessage.getHeaders().setContentType(MediaType.parseMediaType("application/xml;charset=iso-8859-1"));
RootElement result = (RootElement) converter.read(RootElement.class, inputMessage);
assertThat(result.type.s).as("Invalid result").isEqualTo("Hellø Wørld");
}
@Test
void writeXmlRootElement() throws Exception {
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();