Skip to content

Commit c278d8c

Browse files
committed
Do not ignore charset in Jaxb2XmlDecoder
This commit makes sure that the charset, if defined in the mimetype, is used when decoding XML to JAXB2 objects. Closes gh-28599
1 parent e3b2887 commit c278d8c

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.http.codec.xml;
1818

19+
import java.nio.charset.Charset;
1920
import java.util.ArrayList;
2021
import java.util.Iterator;
2122
import java.util.List;
@@ -189,7 +190,7 @@ public Object decode(DataBuffer dataBuffer, ResolvableType targetType,
189190
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) throws DecodingException {
190191

191192
try {
192-
Iterator eventReader = inputFactory.createXMLEventReader(dataBuffer.asInputStream());
193+
Iterator eventReader = inputFactory.createXMLEventReader(dataBuffer.asInputStream(), encoding(mimeType));
193194
List<XMLEvent> events = new ArrayList<>();
194195
eventReader.forEachRemaining(event -> events.add((XMLEvent) event));
195196
return unmarshal(events, targetType.toClass());
@@ -211,6 +212,20 @@ public Object decode(DataBuffer dataBuffer, ResolvableType targetType,
211212
}
212213
}
213214

215+
@Nullable
216+
private static String encoding(@Nullable MimeType mimeType) {
217+
if (mimeType == null) {
218+
return null;
219+
}
220+
Charset charset = mimeType.getCharset();
221+
if (charset == null) {
222+
return null;
223+
}
224+
else {
225+
return charset.name();
226+
}
227+
}
228+
214229
private Object unmarshal(List<XMLEvent> events, Class<?> outputClass) {
215230
try {
216231
Unmarshaller unmarshaller = initUnmarshaller(outputClass);

spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlDecoderTests.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -41,6 +41,7 @@
4141
import org.springframework.http.codec.xml.jaxb.XmlType;
4242
import org.springframework.http.codec.xml.jaxb.XmlTypeWithName;
4343
import org.springframework.http.codec.xml.jaxb.XmlTypeWithNameAndNamespace;
44+
import org.springframework.util.MimeType;
4445
import org.springframework.web.testfixture.xml.Pojo;
4546

4647
import static org.assertj.core.api.Assertions.assertThat;
@@ -228,6 +229,28 @@ public void decodeErrorWithXmlNotWellFormed() {
228229
assertThat(Exceptions.unwrap(ex)).isInstanceOf(DecodingException.class));
229230
}
230231

232+
@Test
233+
public void decodeNonUtf8() {
234+
String xml = "<pojo>" +
235+
"<foo>føø</foo>" +
236+
"<bar>bär</bar>" +
237+
"</pojo>";
238+
Mono<DataBuffer> source = Mono.fromCallable(() -> {
239+
byte[] bytes = xml.getBytes(StandardCharsets.ISO_8859_1);
240+
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);
241+
buffer.write(bytes);
242+
return buffer;
243+
});
244+
MimeType mimeType = new MimeType(MediaType.APPLICATION_XML, StandardCharsets.ISO_8859_1);
245+
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(TypePojo.class), mimeType,
246+
HINTS);
247+
248+
StepVerifier.create(output)
249+
.expectNext(new TypePojo("føø", "bär"))
250+
.expectComplete()
251+
.verify();
252+
}
253+
231254
@Test
232255
public void toExpectedQName() {
233256
assertThat(this.decoder.toQName(Pojo.class)).isEqualTo(new QName("pojo"));

0 commit comments

Comments
 (0)