Spring Boot: 3.5.6 Spring Framework: 6.2.11
When attempting to decode a JSON payload like this
["hello", "world"]
into a String collection using WebFlux' default Codec configuration, the payload is decoded into a single String
with value ["hello","world"]
.
Reproducer:
@RestController
@SpringBootApplication
public class Demo3Application {
public static void main(String[] args) {
SpringApplication.run(Demo3Application.class, args);
}
@GetMapping(path = "/not-empty", produces = MediaType.APPLICATION_JSON_VALUE)
List<String> strings() {
return List.of("hello", "world");
}
@GetMapping(path = "/empty", produces = MediaType.APPLICATION_JSON_VALUE)
List<String> empty() {
return List.of();
}
}
Test:
@WebFluxTest(Demo3Application.class)
class Demo3ApplicationTests {
@Autowired
private WebTestClient c;
@Test
void empty() {
c.get()
.uri("/empty")
.exchange()
.expectStatus().isOk()
.expectBody().json("[]"); // success
c.get()
.uri("/empty")
.exchange()
.expectStatus().isOk()
.expectBodyList(String.class).hasSize(0); // failure, list actually contains a string with value "[]"
}
@Test
void notEmpty() {
c.get()
.uri("/not-empty")
.exchange()
.expectStatus().isOk()
.expectBody().json("""
["hello", "world"]"""); // success
c.get()
.uri("/not-empty")
.exchange()
.expectStatus().isOk()
.expectBodyList(String.class)
.hasSize(2) // failure, actual size is 1
.contains("hello", "world"); // failure, list actually contains a single string with value "[\"hello\",\"world\"]"
}
}
While debugging this I found that StringDecoder
is used to parse the response instead of Jackson2JsonDecoder
. This is unexpected considering the application/json
content type of the response and my requested target type...
A similar issue happens when encoding a Flux<String>
to application/json
. Instead of a JSON array, the response is a plain text concatenation of the individual strings emitted by the Flux
...
Comment From: SuganthiThomas
Hi, I’m interested in working on this issue. I have experience with Java and Spring Boot. Could I take this up?