AbstractJackson2Encoder uses private fields

Make the protected fields in AbstractJackson2Encoder private plus
minor refactoring to the way streaming separators are applied.

The current (5.0.3) behavior is to always use '\n', but in 5.0.4 the
newly supported "application/stream+x-jackson-smile" needs to be
excluded from that. For now, separator determination remains private
in the abstract base class, but current behavior remains which is to
apply '\n' by default.

Issue: SPR-15424
This commit is contained in:
Rossen Stoyanchev 2018-02-14 12:09:07 -05:00
parent 6d7573262e
commit 0ead0503eb
3 changed files with 31 additions and 18 deletions

View File

@ -21,6 +21,7 @@ import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -58,9 +59,18 @@ import org.springframework.util.MimeType;
*/
public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport implements HttpMessageEncoder<Object> {
protected final List<MediaType> streamingMediaTypes = new ArrayList<>(1);
private static final byte[] NEWLINE_SEPARATOR = {'\n'};
protected boolean streamingLineSeparator = true;
private static final Map<MediaType, byte[]> STREAM_SEPARATORS;
static {
STREAM_SEPARATORS = new HashMap<>();
STREAM_SEPARATORS.put(MediaType.APPLICATION_STREAM_JSON, NEWLINE_SEPARATOR);
STREAM_SEPARATORS.put(MediaType.parseMediaType("application/stream+x-jackson-smile"), new byte[0]);
}
private final List<MediaType> streamingMediaTypes = new ArrayList<>(1);
/**
@ -103,20 +113,23 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
return Flux.from(inputStream).map(value ->
encodeValue(value, mimeType, bufferFactory, elementType, hints));
}
else if (this.streamingMediaTypes.stream().anyMatch(mediaType -> mediaType.isCompatibleWith(mimeType))) {
return Flux.from(inputStream).map(value -> {
DataBuffer buffer = encodeValue(value, mimeType, bufferFactory, elementType, hints);
if (streamingLineSeparator) {
buffer.write(new byte[]{'\n'});
}
return buffer;
});
}
else {
ResolvableType listType = ResolvableType.forClassWithGenerics(List.class, elementType);
return Flux.from(inputStream).collectList().map(list ->
encodeValue(list, mimeType, bufferFactory, listType, hints)).flux();
for (MediaType streamingMediaType : this.streamingMediaTypes) {
if (streamingMediaType.isCompatibleWith(mimeType)) {
byte[] separator = STREAM_SEPARATORS.getOrDefault(streamingMediaType, NEWLINE_SEPARATOR);
return Flux.from(inputStream).map(value -> {
DataBuffer buffer = encodeValue(value, mimeType, bufferFactory, elementType, hints);
if (separator != null) {
buffer.write(separator);
}
return buffer;
});
}
}
ResolvableType listType = ResolvableType.forClassWithGenerics(List.class, elementType);
return Flux.from(inputStream).collectList().map(list ->
encodeValue(list, mimeType, bufferFactory, listType, hints)).flux();
}
private DataBuffer encodeValue(Object value, @Nullable MimeType mimeType, DataBufferFactory bufferFactory,

View File

@ -16,6 +16,7 @@
package org.springframework.http.codec.json;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -55,7 +56,7 @@ public class Jackson2JsonEncoder extends AbstractJackson2Encoder {
public Jackson2JsonEncoder(ObjectMapper mapper, MimeType... mimeTypes) {
super(mapper, mimeTypes);
this.streamingMediaTypes.add(MediaType.APPLICATION_STREAM_JSON);
setStreamingMediaTypes(Collections.singletonList(MediaType.APPLICATION_STREAM_JSON));
this.ssePrettyPrinter = initSsePrettyPrinter();
}

View File

@ -51,8 +51,7 @@ public class Jackson2SmileEncoder extends AbstractJackson2Encoder {
public Jackson2SmileEncoder(ObjectMapper mapper, MimeType... mimeTypes) {
super(mapper, mimeTypes);
Assert.isAssignable(SmileFactory.class, mapper.getFactory().getClass());
this.streamingMediaTypes.add(new MediaType("application", "stream+x-jackson-smile"));
this.streamingLineSeparator = false;
setStreamingMediaTypes(Collections.singletonList(new MediaType("application", "stream+x-jackson-smile")));
}
}