提交 3efb76c8 编写于 作者: R Rossen Stoyanchev

Jackson encoder skips String.class

Jackson2Encoder explicitly disables String from the supported types
consistent with the same change on the decoder side:

https://github.com/spring-projects/spring-framework/commit/0662dbf0447d8e788575fcf73fafe248b74cbe8d

Issue: SPR-15443
上级 2ba4a224
...@@ -15,17 +15,22 @@ ...@@ -15,17 +15,22 @@
*/ */
package org.springframework.test.web.reactive.server.samples; package org.springframework.test.web.reactive.server.samples;
import java.net.URI;
import org.junit.Test; import org.junit.Test;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.GetMapping; 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; import org.springframework.web.bind.annotation.RestController;
/** /**
* Sample tests asserting JSON response content. * Samples of tests with serialized JSON content.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
...@@ -55,6 +60,16 @@ public class JsonContentTests { ...@@ -55,6 +60,16 @@ public class JsonContentTests {
.jsonPath("$[2].name").isEqualTo("John"); .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 @RestController
@SuppressWarnings("unused") @SuppressWarnings("unused")
...@@ -64,6 +79,11 @@ public class JsonContentTests { ...@@ -64,6 +79,11 @@ public class JsonContentTests {
Flux<Person> getPersons() { Flux<Person> getPersons() {
return Flux.just(new Person("Jane"), new Person("Jason"), new Person("John")); return Flux.just(new Person("Jane"), new Person("Jason"), new Person("John"));
} }
@PostMapping
ResponseEntity<String> savePerson(@RequestBody Person person) {
return ResponseEntity.created(URI.create("/persons/" + person.getName())).build();
}
} }
} }
...@@ -24,7 +24,6 @@ import java.util.Map; ...@@ -24,7 +24,6 @@ import java.util.Map;
import org.junit.Test; import org.junit.Test;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier; import reactor.test.StepVerifier;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
...@@ -124,7 +123,7 @@ public class ResponseEntityTests { ...@@ -124,7 +123,7 @@ public class ResponseEntityTests {
@Test @Test
public void postEntity() throws Exception { public void postEntity() throws Exception {
this.client.post().uri("/persons") this.client.post().uri("/persons")
.body(Mono.just(new Person("John")), Person.class) .body(new Person("John"))
.exchange() .exchange()
.expectStatus().isCreated() .expectStatus().isCreated()
.expectHeader().valueEquals("location", "/persons/John") .expectHeader().valueEquals("location", "/persons/John")
......
...@@ -69,7 +69,7 @@ public class Jackson2JsonDecoder extends Jackson2CodecSupport implements HttpMes ...@@ -69,7 +69,7 @@ public class Jackson2JsonDecoder extends Jackson2CodecSupport implements HttpMes
@Override @Override
public boolean canDecode(ResolvableType elementType, MimeType mimeType) { public boolean canDecode(ResolvableType elementType, MimeType mimeType) {
JavaType javaType = this.objectMapper.getTypeFactory().constructType(elementType.getType()); 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)) && return (!CharSequence.class.isAssignableFrom(elementType.resolve(Object.class)) &&
this.objectMapper.canDeserialize(javaType) && supportsMimeType(mimeType)); this.objectMapper.canDeserialize(javaType) && supportsMimeType(mimeType));
} }
......
...@@ -105,7 +105,9 @@ public class Jackson2JsonEncoder extends Jackson2CodecSupport implements HttpMes ...@@ -105,7 +105,9 @@ public class Jackson2JsonEncoder extends Jackson2CodecSupport implements HttpMes
@Override @Override
public boolean canEncode(ResolvableType elementType, MimeType mimeType) { public boolean canEncode(ResolvableType elementType, MimeType mimeType) {
Class<?> clazz = elementType.getRawClass(); 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 @Override
......
...@@ -52,7 +52,13 @@ public class Jackson2JsonEncoderTests extends AbstractDataBufferAllocatingTestCa ...@@ -52,7 +52,13 @@ public class Jackson2JsonEncoderTests extends AbstractDataBufferAllocatingTestCa
ResolvableType pojoType = ResolvableType.forClass(Pojo.class); ResolvableType pojoType = ResolvableType.forClass(Pojo.class);
assertTrue(this.encoder.canEncode(pojoType, APPLICATION_JSON)); assertTrue(this.encoder.canEncode(pojoType, APPLICATION_JSON));
assertTrue(this.encoder.canEncode(pojoType, null)); 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); ResolvableType sseType = ResolvableType.forClass(ServerSentEvent.class);
assertFalse(this.encoder.canEncode(sseType, APPLICATION_JSON)); assertFalse(this.encoder.canEncode(sseType, APPLICATION_JSON));
} }
......
...@@ -291,7 +291,7 @@ public class ResponseEntityResultHandlerTests { ...@@ -291,7 +291,7 @@ public class ResponseEntityResultHandlerTests {
this.resultHandler.handleResult(exchange, result).block(Duration.ofSeconds(5)); this.resultHandler.handleResult(exchange, result).block(Duration.ofSeconds(5));
assertEquals(HttpStatus.OK, exchange.getResponse().getStatusCode()); assertEquals(HttpStatus.OK, exchange.getResponse().getStatusCode());
assertResponseBody(exchange, "\"body\""); assertResponseBody(exchange, "body");
} }
@Test // SPR-14877 @Test // SPR-14877
......
...@@ -67,11 +67,11 @@ public class HttpMessageWriterViewTests { ...@@ -67,11 +67,11 @@ public class HttpMessageWriterViewTests {
@Test @Test
public void singleMatch() throws Exception { public void singleMatch() throws Exception {
this.view.setModelKeys(Collections.singleton("foo2")); this.view.setModelKeys(Collections.singleton("foo2"));
this.model.addAttribute("foo1", "bar1"); this.model.addAttribute("foo1", Collections.singleton("bar1"));
this.model.addAttribute("foo2", "bar2"); this.model.addAttribute("foo2", Collections.singleton("bar2"));
this.model.addAttribute("foo3", "bar3"); this.model.addAttribute("foo3", Collections.singleton("bar3"));
assertEquals("\"bar2\"", doRender()); assertEquals("[\"bar2\"]", doRender());
} }
@Test @Test
...@@ -94,11 +94,11 @@ public class HttpMessageWriterViewTests { ...@@ -94,11 +94,11 @@ public class HttpMessageWriterViewTests {
@Test @Test
public void multipleMatches() throws Exception { public void multipleMatches() throws Exception {
this.view.setModelKeys(new HashSet<>(Arrays.asList("foo1", "foo2"))); this.view.setModelKeys(new HashSet<>(Arrays.asList("foo1", "foo2")));
this.model.addAttribute("foo1", "bar1"); this.model.addAttribute("foo1", Collections.singleton("bar1"));
this.model.addAttribute("foo2", "bar2"); this.model.addAttribute("foo2", Collections.singleton("bar2"));
this.model.addAttribute("foo3", "bar3"); this.model.addAttribute("foo3", Collections.singleton("bar3"));
assertEquals("{\"foo1\":\"bar1\",\"foo2\":\"bar2\"}", doRender()); assertEquals("{\"foo1\":[\"bar1\"],\"foo2\":[\"bar2\"]}", doRender());
} }
@Test @Test
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册