序列化Java8流
我想使用Jackson来序列化流的输出。Jackson不支持序列化序列化Java8流,java,json,jackson,Java,Json,Jackson,我想使用Jackson来序列化流的输出。Jackson不支持序列化java.util.stream.stream,但它能够序列化java.util.Iterator 为了说明这个问题,我想序列化这个平凡的接口: public interface SerializeMe { Iterator<Integer> getMyNumbers(); } 以下方法将演示这两个类的输出: public static void main(String[] args) throws Exce
java.util.stream.stream
,但它能够序列化java.util.Iterator
为了说明这个问题,我想序列化这个平凡的接口:
public interface SerializeMe {
Iterator<Integer> getMyNumbers();
}
以下方法将演示这两个类的输出:
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)
公共迭代器getMyNumbers(){
// ....
}
我不想为流可以创建的每个类型迭代器都编写自定义的
JsonSerializer
。我的替代方案是什么?迭代器仅被识别为一个“附加”接口,也就是说,它仅在对象没有可构建的bean序列化程序时使用。不幸的是,spliterator适配器确实构建了一个伪bean序列化程序,因为该类有一个注释。。。这不是很好,甚至似乎与预期不符(这不是检查器使用afaik的注释)
当您指定@JsonSerialize(as=Iterator.class)
时,您将强制解释为迭代器,迭代器序列化器工作正常
这是我之前编写的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);
}
}
}
公共类StreamModule扩展SimpleModule{
公共流模块(){
super(StreamModule.class.getSimpleName());
addSerializer(LongStream.class,新的LongStreamSerializer());
addSerializer(IntStream.class,新的IntStreamSerializer());
addSerializer(DoubleStream.class,新的DoubleStreamSerializer());
}
@凌驾
公共无效设置模块(设置上下文上下文){
addSerializers(新的StreamSerializers());
super.setupModule(上下文);
}
公共静态类StreamSerializers扩展了Serializers.Base{
@凌驾
公共JsonSerializer findSerializer(SerializationConfig配置、JavaType类型、BeanDescription beanDesc){
Class raw=type.getRawClass();
if(Stream.class.isAssignableFrom(原始)){
JavaType[]params=config.getTypeFactory().findTypeParameters(类型,Stream.class);
JavaType vt=(params==null | | params.length!=1)?TypeFactory.unknownType():params[0];
返回新的StreamSerializer(config.getTypeFactory().ConstructParameterizedType(Stream.class,Stream.class,vt),vt);
}
返回super.findSerializer(配置、类型、beanDesc);
}
}
静态类StreamSerializer扩展StdSerializer实现ContextualSerializer{
私有最终JavaType streamType;
私有最终JavaType elemType;
公共StreamSerializer(JavaType streamType、JavaType elemType){
超级(流线型);
this.streamType=streamType;
this.elemType=elemType;
}
@凌驾
公共JsonSerializer createContext(SerializerProvider提供程序,BeanProperty属性)引发JsonMappingException{
if(!elemType.hasRawClass(Object.class)&&(provider.isEnabled(MapperFeature.USE_STATIC_TYPING)| | elemType.isFinal()){
JsonSerializer elemSerializer=provider.findPrimaryPropertySerializer(elemType,property);
返回新的TypedStreamSerializer(streamType、elemSerializer);
}
归还这个;
}
@凌驾
public void serialize(Stream、JsonGenerator jgen、SerializerProvider提供程序)引发IOException,
JsonGenerationException{
jgen.writestarray();
试一试{
stream.forEachOrdered(元素->{
试一试{
provider.defaultSerializeValue(elem,jgen);
}捕获(IOE异常){
抛出新的WrappedIOException(e);
}
});
}捕获(包裹){
抛出(IOException)e.getCause();
}
jgen.writeEndArray();
}
}
静态类TypedStreamSerializer扩展了StdSerializer{
私人最终JsonSerializer elemSerializer;
@抑制警告(“未选中”)
公共类型流序列化程序(JavaType streamType、JsonSerializer和elemSerializer){
超级(流线型);
this.elemSerializer=(JsonSerializer)elemSerializer;
}
@凌驾
public void serialize(Stream、JsonGenerator jgen、SerializerProvider提供程序)引发IOException,
JsonGenerationException{
jgen.writestarray();
试一试{
stream.forEachOrdered(元素->{
试一试{
序列化(elem,jgen,provider);
}捕获(IOE异常){
抛出新的WrappedIOException(e);
}
});
}捕获(包裹){
抛出(IOException)e.getCause();
}
jgen.writeEndArray();
}
}
静态类IntStreamSerializer扩展了StdSerializer{
公共IntStreamSerializer(){
super(IntStream.class);
}
@凌驾
public void serialize(IntStream流、JsonGenerator jgen、SerializerProvider提供程序)引发IOException,
JsonGenerationException{
jgen.writestarray();
试一试{
stream.forEachOrdered(值->{
试一试{
jgen.writeNumber(值);
}捕获(IOE异常){
抛出新的W
@JsonSerialize(as=Iterator.class)
public Iterator<Integer> getMyNumbers() {
// ....
}
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);
}
}
}