提交 eb971690 编写于 作者: J Juergen Hoeller

Merge branch '5.1.x'

......@@ -87,7 +87,7 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
Flux<TokenBuffer> tokens = Jackson2Tokenizer.tokenize(
Flux.from(input), this.jsonFactory, getObjectMapper().getDeserializationContext(), true);
Flux.from(input), this.jsonFactory, getObjectMapper(), true);
return decodeInternal(tokens, elementType, mimeType, hints);
}
......@@ -96,7 +96,7 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
Flux<TokenBuffer> tokens = Jackson2Tokenizer.tokenize(
Flux.from(input), this.jsonFactory, getObjectMapper().getDeserializationContext(), false);
Flux.from(input), this.jsonFactory, getObjectMapper(), false);
return decodeInternal(tokens, elementType, mimeType, hints).singleOrEmpty();
}
......
......@@ -27,6 +27,8 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.async.ByteArrayFeeder;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.DefaultDeserializationContext;
import com.fasterxml.jackson.databind.util.TokenBuffer;
import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
......@@ -177,16 +179,22 @@ final class Jackson2Tokenizer {
* Tokenize the given {@code Flux<DataBuffer>} into {@code Flux<TokenBuffer>}.
* @param dataBuffers the source data buffers
* @param jsonFactory the factory to use
* @param objectMapper the current mapper instance
* @param tokenizeArrayElements if {@code true} and the "top level" JSON object is
* an array, each element is returned individually immediately after it is received
* @return the resulting token buffers
*/
public static Flux<TokenBuffer> tokenize(Flux<DataBuffer> dataBuffers, JsonFactory jsonFactory,
DeserializationContext deserializationContext, boolean tokenizeArrayElements) {
ObjectMapper objectMapper, boolean tokenizeArrayElements) {
try {
JsonParser parser = jsonFactory.createNonBlockingByteArrayParser();
Jackson2Tokenizer tokenizer = new Jackson2Tokenizer(parser, deserializationContext, tokenizeArrayElements);
DeserializationContext context = objectMapper.getDeserializationContext();
if (context instanceof DefaultDeserializationContext) {
context = ((DefaultDeserializationContext) context).createInstance(
objectMapper.getDeserializationConfig(), parser, objectMapper.getInjectableValues());
}
Jackson2Tokenizer tokenizer = new Jackson2Tokenizer(parser, context, tokenizeArrayElements);
return dataBuffers.concatMapIterable(tokenizer::tokenize).concatWith(tokenizer.endOfInput());
}
catch (IOException ex) {
......
......@@ -184,22 +184,18 @@ public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
@Test
public void errorInStream() {
DataBuffer buffer = stringBuffer("{\"id\":1,\"name\":");
Flux<DataBuffer> source = Flux.just(buffer)
.concatWith(Flux.error(new RuntimeException()));
Flux<TokenBuffer> result = Jackson2Tokenizer.tokenize(
source, this.jsonFactory, this.objectMapper.getDeserializationContext(), true);
Flux<DataBuffer> source = Flux.just(buffer).concatWith(Flux.error(new RuntimeException()));
Flux<TokenBuffer> result = Jackson2Tokenizer.tokenize(source, this.jsonFactory, this.objectMapper, true);
StepVerifier.create(result)
.expectError(RuntimeException.class)
.verify();
}
@Test // SPR-16521
@Test // SPR-16521
public void jsonEOFExceptionIsWrappedAsDecodingError() {
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"status\": \"noClosingQuote}"));
Flux<TokenBuffer> tokens = Jackson2Tokenizer.tokenize(
source, this.jsonFactory, this.objectMapper.getDeserializationContext(), false);
Flux<TokenBuffer> tokens = Jackson2Tokenizer.tokenize(source, this.jsonFactory, this.objectMapper, false);
StepVerifier.create(tokens)
.expectError(DecodingException.class)
......@@ -208,12 +204,11 @@ public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
private void testTokenize(List<String> source, List<String> expected, boolean tokenizeArrayElements) {
Flux<TokenBuffer> tokenBufferFlux = Jackson2Tokenizer.tokenize(
Flux<TokenBuffer> tokens = Jackson2Tokenizer.tokenize(
Flux.fromIterable(source).map(this::stringBuffer),
this.jsonFactory, this.objectMapper.getDeserializationContext(),
tokenizeArrayElements);
this.jsonFactory, this.objectMapper, tokenizeArrayElements);
Flux<String> result = tokenBufferFlux
Flux<String> result = tokens
.map(tokenBuffer -> {
try {
TreeNode root = this.objectMapper.readTree(tokenBuffer.asParser());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册