StringHttpMessageConverter.canWrite(String.class, APPLICATION_JSON) shouldn't return true, It will take over before other actual json converters. https://github.com/spring-projects/spring-framework/blob/708e61a7efbe727f91cc385c8d70a31f2fb0e972/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java#L901-L965
here is test case:
@RestController
@RequestMapping("/echo")
public class EchoController {
@PostMapping(consumes = { TEXT_PLAIN_VALUE, APPLICATION_JSON_VALUE }, produces = { TEXT_PLAIN_VALUE,
APPLICATION_JSON_VALUE })
public String echo(@RequestBody String string) {
return "echo:" + string;
}
}
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
@AutoConfigureMockMvc
class EchoControllerTests {
@Autowired
MockMvc mockMvc;
@Test
void acceptText() throws Exception {
mockMvc.perform(post("/echo").contentType(TEXT_PLAIN).accept(TEXT_PLAIN).content("test"))
.andExpect(status().isOk()).andExpect(content().string("echo:test"));
}
@Test
void acceptJson() throws Exception {
mockMvc.perform(post("/echo").contentType(TEXT_PLAIN).accept(APPLICATION_JSON).content("test"))
.andExpect(status().isOk()).andExpect(content().json("\"echo:test\""));
// test failed, content is echo:test, not converted to valid json "echo:test"
}
}
Comment From: rstoyanchev
This is by design. StringHttpMessageConverter writes a String with any content type, similar to ByteArrayHttpMessageConverter. The String or byte[] is serialized content. For JSON serialization you need an Object or Map as a top-level container.