【问题标题】:Java Apache Pair Serializes in one format and Deserializes in different format using Jackson SerializeJava Apache Pair 以一种格式序列化并使用 Jackson Serialize 以不同格式反序列化
【发布时间】:2019-04-09 06:56:59
【问题描述】:

当使用Jackson@JsonSerialize注解序列化Apache Mutable Pair时,这是生成的结构

{"leftValue": "rightValue"}

但是在反序列化过程中使用Jackson @JsonDeserialize 注释进行处理,它需要这种结构

{
"left":"leftValue",
"right": "rightValue"
}

getLeft()getValue() 等方法在使用第一个结构时返回 null,但在使用第二个结构时返回正确的值。

如何序列化成第二个结构?还有推荐的结构是什么?

【问题讨论】:

    标签: java json apache rest jackson


    【解决方案1】:

    org.apache.commons.lang3.tuple.MutablePair 扩展了Pair,实现了Map.Entry 接口。 Map.Entry 默认被Jackson 视为Map 对象,该对象被序列化为JSON 作为key-value 结构。要像经典的POJO 一样序列化它,我们需要实现自定义序列化器,它将定义正确的结构:

    class MutablePairJsonSerializer extends JsonSerializer<MutablePair> {
    
        @Override
        public void serialize(MutablePair value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeStartObject();
            gen.writeObjectField("left", value.getLeft());
            gen.writeObjectField("right", value.getRight());
            gen.writeEndObject();
        }
    }
    

    使用上述序列化程序的简单应用:

    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonDeserializer;
    import com.fasterxml.jackson.databind.JsonSerializer;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    import com.fasterxml.jackson.databind.SerializerProvider;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    import org.apache.commons.lang3.tuple.MutablePair;
    
    import java.io.IOException;
    
    public class JsonApp {
    
        public static void main(String[] args) throws Exception {
            MutablePair<String, String> pair = new MutablePair<>();
            pair.setLeft("leftV");
            pair.setRight("rightV");
    
            SimpleModule pairModule = new SimpleModule();
            pairModule.addSerializer(MutablePair.class, new MutablePairJsonSerializer());
    
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
            mapper.registerModule(pairModule);
    
            String json = mapper.writeValueAsString(pair);
            System.out.println(json);
            System.out.println(mapper.readValue(json, MutablePair.class));
        }
    }
    

    打印:

    {
      "left" : "leftV",
      "right" : "rightV"
    }
    (leftV,rightV)
    

    这表明对象已使用键序列化并正确反序列化为对象。

    如果我们想保持默认的序列化过程,我们需要自定义反序列化器,如下所示:

    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonDeserializer;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.SerializationFeature;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    import org.apache.commons.lang3.tuple.MutablePair;
    
    import java.io.IOException;
    
    public class JsonApp {
    
        public static void main(String[] args) throws Exception {
            MutablePair<String, String> pair = new MutablePair<>();
            pair.setLeft("leftV");
            pair.setRight("rightV");
    
            SimpleModule pairModule = new SimpleModule();
            pairModule.addDeserializer(MutablePair.class, new MutablePairJsonDeserializer());
    
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
            mapper.registerModule(pairModule);
    
            String json = mapper.writeValueAsString(pair);
            System.out.println(json);
            System.out.println(mapper.readValue(json, MutablePair.class));
        }
    }
    
    class MutablePairJsonDeserializer extends JsonDeserializer<MutablePair> {
    
        @Override
        public MutablePair deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            p.nextToken(); // SKIP START_OBJECT
            String keyName = p.getCurrentName();
            p.nextToken();
    
            return MutablePair.of(keyName, p.getValueAsString());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-09-25
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 2011-07-09
      • 2013-09-25
      • 2017-05-30
      • 1970-01-01
      • 2014-01-06
      相关资源
      最近更新 更多