From 92bb76f3cd07b255300f213a8469adeaea6e71e1 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 6 Sep 2018 16:20:03 -0400 Subject: [PATCH] Disable Jackson's buffer recyling feature for WebFlux Issue: SPR-17193 --- .../codec/json/AbstractJackson2Decoder.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) 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 0acdbdedb9..a750beda3e 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,11 +55,20 @@ import org.springframework.util.MimeType; */ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport implements HttpMessageDecoder { + /** + * Until https://github.com/FasterXML/jackson-core/issues/476 is resolved, + * we need to ensure buffer recycling is off. + */ + private final JsonFactory jsonFactory; + + /** * Constructor with a Jackson {@link ObjectMapper} to use. */ protected AbstractJackson2Decoder(ObjectMapper mapper, MimeType... mimeTypes) { super(mapper, mimeTypes); + this.jsonFactory = mapper.getFactory().copy() + .disable(JsonFactory.Feature.USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING); } @@ -75,7 +84,7 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple public Flux decode(Publisher input, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map hints) { - Flux tokens = tokenize(input, true); + Flux tokens = Jackson2Tokenizer.tokenize(Flux.from(input), this.jsonFactory, true); return decodeInternal(tokens, elementType, mimeType, hints); } @@ -83,16 +92,10 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple public Mono decodeToMono(Publisher input, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map hints) { - Flux tokens = tokenize(input, false); + Flux tokens = Jackson2Tokenizer.tokenize(Flux.from(input), this.jsonFactory, false); return decodeInternal(tokens, elementType, mimeType, hints).singleOrEmpty(); } - private Flux tokenize(Publisher input, boolean tokenizeArrayElements) { - Flux inputFlux = Flux.from(input); - JsonFactory factory = getObjectMapper().getFactory(); - return Jackson2Tokenizer.tokenize(inputFlux, factory, tokenizeArrayElements); - } - private Flux decodeInternal(Flux tokens, ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map hints) {