When using Spring Boot 4's WebClient to send an XML request with a String body and Content-Type: application/xml, the request fails with:
Stream decoding is currently not supported
Minimal Reproducer:
webClient
.post()
.uri(url)
.contentType(MediaType.APPLICATION_XML)
.bodyValue("<xml><a>test</a></xml>")
.retrieve();
Root Cause Analysis
The failure is caused by JacksonXmlEncoder#canEncode, which returns true for MediaType.APPLICATION_XML + String.
However, Jackson’s XML encoder does not actually support encoding raw String values.
This behavior differs from JacksonJsonEncoder, which explicitly prevents this case via:
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
return super.canEncode(elementType, mimeType) && !String.class.isAssignableFrom(elementType.toClass());
}
JacksonXmlEncoder does not override canEncode, so it incorrectly signals support for String bodies.
Expected Behavior
JacksonXmlEncoder.canEncode should return false for String types, similar to JacksonJsonEncoder. And falls back to a non-streaming encoder for String bodies with application/xml.
When using Spring Boot 4's WebClient to send an XML request with a String body and Content-Type: application/xml, the request fails with:
Minimal Reproducer:
Root Cause Analysis
The failure is caused by
JacksonXmlEncoder#canEncode, which returns true for MediaType.APPLICATION_XML + String.However, Jackson’s XML encoder does not actually support encoding raw String values.
This behavior differs from
JacksonJsonEncoder, which explicitly prevents this case via:JacksonXmlEncoder does not override canEncode, so it incorrectly signals support for String bodies.
Expected Behavior
JacksonXmlEncoder.canEncode should return false for String types, similar to JacksonJsonEncoder. And falls back to a non-streaming encoder for String bodies with application/xml.