diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java index f0b31f65a4e..03e5ea2c17e 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Decoder.java @@ -44,6 +44,7 @@ import org.springframework.core.codec.Hints; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferLimitException; import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.core.io.buffer.PooledDataBuffer; import org.springframework.core.log.LogFormatUtils; import org.springframework.http.codec.HttpMessageDecoder; import org.springframework.http.server.reactive.ServerHttpRequest; @@ -162,7 +163,8 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple catch (IOException ex) { sink.error(processException(ex)); } - }); + }) + .doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release); }); } diff --git a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java index 023231d4846..ea1406dea52 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java @@ -117,7 +117,7 @@ class Jackson2JsonDecoderTests extends AbstractDecoderTests } @Test // SPR-15866 - public void canDecodeWithProvidedMimeType() { + void canDecodeWithProvidedMimeType() { MimeType textJavascript = new MimeType("text", "javascript", StandardCharsets.UTF_8); Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(new ObjectMapper(), textJavascript); @@ -239,7 +239,7 @@ class Jackson2JsonDecoderTests extends AbstractDecoderTests } @Test // gh-22042 - public void decodeWithNullLiteral() { + void decodeWithNullLiteral() { Flux result = this.decoder.decode(Flux.concat(stringBuffer("null")), ResolvableType.forType(Pojo.class), MediaType.APPLICATION_JSON, Collections.emptyMap()); @@ -247,7 +247,7 @@ class Jackson2JsonDecoderTests extends AbstractDecoderTests } @Test // gh-27511 - public void noDefaultConstructor() { + void noDefaultConstructor() { Flux input = Flux.from(stringBuffer("{\"property1\":\"foo\",\"property2\":\"bar\"}")); testDecode(input, BeanWithNoDefaultConstructor.class, step -> step @@ -268,7 +268,7 @@ class Jackson2JsonDecoderTests extends AbstractDecoderTests } @Test // SPR-15975 - public void customDeserializer() { + void customDeserializer() { Mono input = stringBuffer("{\"test\": 1}"); testDecode(input, TestObject.class, step -> step @@ -289,7 +289,7 @@ class Jackson2JsonDecoderTests extends AbstractDecoderTests @Test @SuppressWarnings("unchecked") - public void decodeNonUtf8Encoding() { + void decodeNonUtf8Encoding() { Mono input = stringBuffer("{\"foo\":\"bar\"}", StandardCharsets.UTF_16); ResolvableType type = ResolvableType.forType(new ParameterizedTypeReference>() {}); @@ -302,7 +302,7 @@ class Jackson2JsonDecoderTests extends AbstractDecoderTests @Test @SuppressWarnings("unchecked") - public void decodeNonUnicode() { + void decodeNonUnicode() { Flux input = Flux.concat(stringBuffer("{\"føø\":\"bår\"}", StandardCharsets.ISO_8859_1)); ResolvableType type = ResolvableType.forType(new ParameterizedTypeReference>() {}); @@ -315,7 +315,7 @@ class Jackson2JsonDecoderTests extends AbstractDecoderTests @Test @SuppressWarnings("unchecked") - public void decodeMonoNonUtf8Encoding() { + void decodeMonoNonUtf8Encoding() { Mono input = stringBuffer("{\"foo\":\"bar\"}", StandardCharsets.UTF_16); ResolvableType type = ResolvableType.forType(new ParameterizedTypeReference>() {}); @@ -328,7 +328,7 @@ class Jackson2JsonDecoderTests extends AbstractDecoderTests @Test @SuppressWarnings("unchecked") - public void decodeAscii() { + void decodeAscii() { Flux input = Flux.concat(stringBuffer("{\"foo\":\"bar\"}", StandardCharsets.US_ASCII)); ResolvableType type = ResolvableType.forType(new ParameterizedTypeReference>() {}); @@ -339,6 +339,15 @@ class Jackson2JsonDecoderTests extends AbstractDecoderTests null); } + @Test + void cancelWhileDecoding() { + Flux input = Flux.just( + stringBuffer("[{\"bar\":\"b1\",\"foo\":\"f1\"},").block(), + stringBuffer("{\"bar\":\"b2\",\"foo\":\"f2\"}]").block()); + + testDecodeCancel(input, ResolvableType.forClass(Pojo.class), null, null); + } + private Mono stringBuffer(String value) { return stringBuffer(value, StandardCharsets.UTF_8);