From 6e51370490bfda56d4ce68b1acaffb858df7af46 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 6 Nov 2020 20:46:35 +0000 Subject: [PATCH] AbstractJackson2Encoder support for MappingJacksonValue Closes gh-26035 --- .../codec/json/AbstractJackson2Encoder.java | 23 +++++++++++++++---- .../codec/json/Jackson2JsonEncoderTests.java | 20 ++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java index ae90df4115f..a5bfda5625f 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java @@ -34,6 +34,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.SequenceWriter; import com.fasterxml.jackson.databind.exc.InvalidDefinitionException; +import com.fasterxml.jackson.databind.ser.FilterProvider; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -48,6 +49,7 @@ import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.log.LogFormatUtils; import org.springframework.http.MediaType; import org.springframework.http.codec.HttpMessageEncoder; +import org.springframework.http.converter.json.MappingJacksonValue; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.lang.Nullable; @@ -148,7 +150,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple byte[] separator = getStreamingMediaTypeSeparator(mimeType); if (separator != null) { // streaming try { - ObjectWriter writer = createObjectWriter(elementType, mimeType, hints); + ObjectWriter writer = createObjectWriter(elementType, mimeType, null, hints); ByteArrayBuilder byteBuilder = new ByteArrayBuilder(writer.getFactory()._getBufferRecycler()); JsonEncoding encoding = getJsonEncoding(mimeType); JsonGenerator generator = getObjectMapper().getFactory().createGenerator(byteBuilder, encoding); @@ -186,7 +188,18 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple public DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory, ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map hints) { - ObjectWriter writer = createObjectWriter(valueType, mimeType, hints); + Class jsonView = null; + FilterProvider filters = null; + if (value instanceof MappingJacksonValue) { + MappingJacksonValue container = (MappingJacksonValue) value; + value = container.getValue(); + jsonView = container.getSerializationView(); + filters = container.getFilters(); + } + ObjectWriter writer = createObjectWriter(valueType, mimeType, jsonView, hints); + if (filters != null) { + writer = writer.with(filters); + } ByteArrayBuilder byteBuilder = new ByteArrayBuilder(writer.getFactory()._getBufferRecycler()); try { JsonEncoding encoding = getJsonEncoding(mimeType); @@ -268,10 +281,12 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple } private ObjectWriter createObjectWriter(ResolvableType valueType, @Nullable MimeType mimeType, - @Nullable Map hints) { + @Nullable Class jsonView, @Nullable Map hints) { JavaType javaType = getJavaType(valueType.getType(), null); - Class jsonView = (hints != null ? (Class) hints.get(Jackson2CodecSupport.JSON_VIEW_HINT) : null); + if (jsonView == null && hints != null) { + jsonView = (Class) hints.get(Jackson2CodecSupport.JSON_VIEW_HINT); + } ObjectWriter writer = (jsonView != null ? getObjectMapper().writerWithView(jsonView) : getObjectMapper().writer()); 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 0a9d3274126..ebeed1493b7 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 @@ -39,6 +39,7 @@ import org.springframework.http.MediaType; import org.springframework.http.codec.ServerSentEvent; import org.springframework.http.codec.json.JacksonViewBean.MyJacksonView1; import org.springframework.http.codec.json.JacksonViewBean.MyJacksonView3; +import org.springframework.http.converter.json.MappingJacksonValue; import org.springframework.util.MimeType; import org.springframework.util.MimeTypeUtils; import org.springframework.web.testfixture.xml.Pojo; @@ -214,6 +215,25 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests step + .consumeNextWith(expectString("{\"withView1\":\"with\"}") + .andThen(DataBufferUtils::release)) + .verifyComplete(), + null, Collections.emptyMap()); + } + @Test // gh-22771 public void encodeWithFlushAfterWriteOff() { ObjectMapper mapper = new ObjectMapper();