我想使用Jackson来序列化流的输出。Jackson对序列化java.util.stream.Stream没有内在的支持,但它能够序列化java.util.Iterator。
为了说明这个问题,我想序列化这个简单的接口:
public interface SerializeMe {
Iterator<Integer> getMyNumbers();
}我将比较序列化List.iterator()与Stream.iterator()的输出。
public class SerializeViaList implements SerializeMe {
@Override
public Iterator<Integer> getMyNumbers() {
return Arrays.asList(1, 2, 3).iterator();
}
}
public class SerializeViaStream implements SerializeMe {
@Override
public Iterator<Integer> getMyNumbers() {
return Arrays.asList(1, 2, 3).stream().iterator();
}
}下面的方法将演示这两个类的输出:
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
System.out.println("via list: " + mapper.writeValueAsString(new SerializeViaList()));
System.out.println("via stream: " + mapper.writeValueAsString(new SerializeViaStream()));
}它的输出是:
via list: {"myNumbers":[1,2,3]}
via stream: {"myNumbers":{}}这说明流迭代器没有正确序列化。
有趣的是,如果我添加@JsonSerialize(as=Iterator.class),它确实有效。
@JsonSerialize(as=Iterator.class)
public Iterator<Integer> getMyNumbers() {
// ....
}我不想为流可以创建的每个类型的迭代器编写一个自定义的JsonSerializer。我有什么选择?
发布于 2016-01-13 13:33:42
Iterator只被认为是一个“附加”接口,也就是说,只有在没有为对象构建bean序列化程序的情况下才使用Iterator。不幸的是,分配器适配器确实得到了一个虚拟bean序列化器,因为这个类有一个注释.这一点也不太好,甚至看起来也不太符合预期(这不是检查员使用afaik的注释)。
当您指定@JsonSerialize(as=Iterator.class)时,您强制将解释作为一个Iterator,而IteratorSerializer工作得很好。
这是我之前编写的一个Jackson模块,它允许序列化流(也包括LongStream、IntStream或DoubleStream),方法是按顺序序列化其内容:
public class StreamModule extends SimpleModule {
public StreamModule() {
super(StreamModule.class.getSimpleName());
addSerializer(LongStream.class, new LongStreamSerializer());
addSerializer(IntStream.class, new IntStreamSerializer());
addSerializer(DoubleStream.class, new DoubleStreamSerializer());
}
@Override
public void setupModule(SetupContext context) {
context.addSerializers(new StreamSerializers());
super.setupModule(context);
}
public static class StreamSerializers extends Serializers.Base {
@Override
public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) {
Class<?> raw = type.getRawClass();
if (Stream.class.isAssignableFrom(raw)) {
JavaType[] params = config.getTypeFactory().findTypeParameters(type, Stream.class);
JavaType vt = (params == null || params.length != 1) ? TypeFactory.unknownType() : params[0];
return new StreamSerializer<Object>(config.getTypeFactory().constructParametrizedType(Stream.class, Stream.class, vt), vt);
}
return super.findSerializer(config, type, beanDesc);
}
}
static class StreamSerializer<T> extends StdSerializer<Stream<T>> implements ContextualSerializer {
private final JavaType streamType;
private final JavaType elemType;
public StreamSerializer(JavaType streamType, JavaType elemType) {
super(streamType);
this.streamType = streamType;
this.elemType = elemType;
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException {
if (!elemType.hasRawClass(Object.class) && (provider.isEnabled(MapperFeature.USE_STATIC_TYPING) || elemType.isFinal())) {
JsonSerializer<Object> elemSerializer = provider.findPrimaryPropertySerializer(elemType, property);
return new TypedStreamSerializer<T>(streamType, elemSerializer);
}
return this;
}
@Override
public void serialize(Stream<T> stream, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonGenerationException {
jgen.writeStartArray();
try {
stream.forEachOrdered(elem -> {
try {
provider.defaultSerializeValue(elem, jgen);
} catch (IOException e) {
throw new WrappedIOException(e);
}
});
} catch (WrappedIOException e) {
throw (IOException) e.getCause();
}
jgen.writeEndArray();
}
}
static class TypedStreamSerializer<T> extends StdSerializer<Stream<T>> {
private final JsonSerializer<T> elemSerializer;
@SuppressWarnings("unchecked")
public TypedStreamSerializer(JavaType streamType, JsonSerializer<?> elemSerializer) {
super(streamType);
this.elemSerializer = (JsonSerializer<T>) elemSerializer;
}
@Override
public void serialize(Stream<T> stream, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonGenerationException {
jgen.writeStartArray();
try {
stream.forEachOrdered(elem -> {
try {
elemSerializer.serialize(elem, jgen, provider);
} catch (IOException e) {
throw new WrappedIOException(e);
}
});
} catch (WrappedIOException e) {
throw (IOException) e.getCause();
}
jgen.writeEndArray();
}
}
static class IntStreamSerializer extends StdSerializer<IntStream> {
public IntStreamSerializer() {
super(IntStream.class);
}
@Override
public void serialize(IntStream stream, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonGenerationException {
jgen.writeStartArray();
try {
stream.forEachOrdered(value -> {
try {
jgen.writeNumber(value);
} catch (IOException e) {
throw new WrappedIOException(e);
}
});
} catch (WrappedIOException e) {
throw (IOException) e.getCause();
}
jgen.writeEndArray();
}
}
static class LongStreamSerializer extends StdSerializer<LongStream> {
public LongStreamSerializer() {
super(LongStream.class);
}
@Override
public void serialize(LongStream stream, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonGenerationException {
jgen.writeStartArray();
try {
stream.forEachOrdered(value -> {
try {
jgen.writeNumber(value);
} catch (IOException e) {
throw new WrappedIOException(e);
}
});
} catch (WrappedIOException e) {
throw (IOException) e.getCause();
}
jgen.writeEndArray();
}
}
static class DoubleStreamSerializer extends StdSerializer<DoubleStream> {
public DoubleStreamSerializer() {
super(DoubleStream.class);
}
@Override
public void serialize(DoubleStream stream, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonGenerationException {
jgen.writeStartArray();
try {
stream.forEachOrdered(value -> {
try {
jgen.writeNumber(value);
} catch (IOException e) {
throw new WrappedIOException(e);
}
});
} catch (WrappedIOException e) {
throw (IOException) e.getCause();
}
jgen.writeEndArray();
}
}
public static final class WrappedIOException extends RuntimeException {
private WrappedIOException(IOException e) {
super(e);
}
}
}https://stackoverflow.com/questions/34748282
复制相似问题