diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java index f1fc414eafd810859c3095015e41b4eb186c483c..184525ac690416a860586b8401194bb9382bc4a5 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java @@ -15,17 +15,22 @@ */ package org.springframework.test.web.reactive.server.samples; +import java.net.URI; + import org.junit.Test; import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; /** - * Sample tests asserting JSON response content. + * Samples of tests with serialized JSON content. * * @author Rossen Stoyanchev */ @@ -55,6 +60,16 @@ public class JsonContentTests { .jsonPath("$[2].name").isEqualTo("John"); } + @Test + public void postJsonContent() throws Exception { + this.client.post().uri("/persons") + .contentType(MediaType.APPLICATION_JSON_UTF8) + .body("{\"name\":\"John\"}") + .exchange() + .expectStatus().isCreated() + .expectBody().isEmpty(); + } + @RestController @SuppressWarnings("unused") @@ -64,6 +79,11 @@ public class JsonContentTests { Flux getPersons() { return Flux.just(new Person("Jane"), new Person("Jason"), new Person("John")); } + + @PostMapping + ResponseEntity savePerson(@RequestBody Person person) { + return ResponseEntity.created(URI.create("/persons/" + person.getName())).build(); + } } } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java index 19f7dc2472e49c4ffbc708c117ab1f7174bbb400..a8d4680927b4955cd7512c6ebc2a2e97684ff0ac 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java @@ -24,7 +24,6 @@ import java.util.Map; import org.junit.Test; import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import org.springframework.http.MediaType; @@ -124,7 +123,7 @@ public class ResponseEntityTests { @Test public void postEntity() throws Exception { this.client.post().uri("/persons") - .body(Mono.just(new Person("John")), Person.class) + .body(new Person("John")) .exchange() .expectStatus().isCreated() .expectHeader().valueEquals("location", "/persons/John") diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java index bbb5f4724b4b8b91c1dcf37c86b93518ea82b108..3333558aaa55d3fed1dbfc4b1dc490c78bf8378f 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java @@ -69,7 +69,7 @@ public class Jackson2JsonDecoder extends Jackson2CodecSupport implements HttpMes @Override public boolean canDecode(ResolvableType elementType, MimeType mimeType) { JavaType javaType = this.objectMapper.getTypeFactory().constructType(elementType.getType()); - // Skip String (CharSequenceDecoder + "*/*" comes after) + // Skip String: CharSequenceDecoder + "*/*" comes after return (!CharSequence.class.isAssignableFrom(elementType.resolve(Object.class)) && this.objectMapper.canDeserialize(javaType) && supportsMimeType(mimeType)); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java index 467d773ca0ccc865af2e58c5d5abb00b6bea6b04..54843adb0cf2b016bf58c4876206e9f61f9ec094 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java @@ -105,7 +105,9 @@ public class Jackson2JsonEncoder extends Jackson2CodecSupport implements HttpMes @Override public boolean canEncode(ResolvableType elementType, MimeType mimeType) { Class clazz = elementType.getRawClass(); - return (this.objectMapper.canSerialize(clazz) && supportsMimeType(mimeType)); + // Skip String: StringDecoder + "*/*" comes after + return (!String.class.isAssignableFrom(elementType.resolve(Object.class)) && + this.objectMapper.canSerialize(clazz) && supportsMimeType(mimeType)); } @Override diff --git a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java index 6c808311c2a8127288a8e569919882d75ea66d0d..56d7c83cab2c498c2138a246068da6be25388dd6 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java @@ -52,7 +52,13 @@ public class Jackson2JsonEncoderTests extends AbstractDataBufferAllocatingTestCa ResolvableType pojoType = ResolvableType.forClass(Pojo.class); assertTrue(this.encoder.canEncode(pojoType, APPLICATION_JSON)); assertTrue(this.encoder.canEncode(pojoType, null)); - assertFalse(this.encoder.canEncode(pojoType, APPLICATION_XML)); + } + + @Test + public void canNotEncode() { + assertFalse(this.encoder.canEncode(ResolvableType.forClass(String.class), null)); + assertFalse(this.encoder.canEncode(ResolvableType.forClass(Pojo.class), APPLICATION_XML)); + ResolvableType sseType = ResolvableType.forClass(ServerSentEvent.class); assertFalse(this.encoder.canEncode(sseType, APPLICATION_JSON)); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java index b1333793793e5fe10eb1936483142351e1ef1331..f27fb75b3440fc73b9e377c2cc95692fb4e1bf7c 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java @@ -291,7 +291,7 @@ public class ResponseEntityResultHandlerTests { this.resultHandler.handleResult(exchange, result).block(Duration.ofSeconds(5)); assertEquals(HttpStatus.OK, exchange.getResponse().getStatusCode()); - assertResponseBody(exchange, "\"body\""); + assertResponseBody(exchange, "body"); } @Test // SPR-14877 diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java index 2a25353e0fe194b4b769eca7619d8d9b774d3ef4..356baf4f32f0842bce94f628be8dceaeace71a02 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/HttpMessageWriterViewTests.java @@ -67,11 +67,11 @@ public class HttpMessageWriterViewTests { @Test public void singleMatch() throws Exception { this.view.setModelKeys(Collections.singleton("foo2")); - this.model.addAttribute("foo1", "bar1"); - this.model.addAttribute("foo2", "bar2"); - this.model.addAttribute("foo3", "bar3"); + this.model.addAttribute("foo1", Collections.singleton("bar1")); + this.model.addAttribute("foo2", Collections.singleton("bar2")); + this.model.addAttribute("foo3", Collections.singleton("bar3")); - assertEquals("\"bar2\"", doRender()); + assertEquals("[\"bar2\"]", doRender()); } @Test @@ -94,11 +94,11 @@ public class HttpMessageWriterViewTests { @Test public void multipleMatches() throws Exception { this.view.setModelKeys(new HashSet<>(Arrays.asList("foo1", "foo2"))); - this.model.addAttribute("foo1", "bar1"); - this.model.addAttribute("foo2", "bar2"); - this.model.addAttribute("foo3", "bar3"); + this.model.addAttribute("foo1", Collections.singleton("bar1")); + this.model.addAttribute("foo2", Collections.singleton("bar2")); + this.model.addAttribute("foo3", Collections.singleton("bar3")); - assertEquals("{\"foo1\":\"bar1\",\"foo2\":\"bar2\"}", doRender()); + assertEquals("{\"foo1\":[\"bar1\"],\"foo2\":[\"bar2\"]}", doRender()); } @Test