【问题标题】:Jackson - serialization of Map<String, Object> implementationJackson - Map<String, Object> 实现的序列化
【发布时间】:2017-05-09 23:42:56
【问题描述】:

我有以下课程:

public class Some implements Map<String, Object>{
    private Map<String, Object> innerMap;
    //implementation that can only set innerMap in constructor and cannot add or remove values
}

问题是我无法在 jackson 中正确反序列化它。如果我在没有默认类型的情况下进行序列化,那没关系,因为它被序列化为 {"one":"two"} 并正确反序列化(我必须使用

实现反序列化器
return new Some(jp.readValueAs(new TypeReference<HashMap<String,Object>>(){}));

当我使用默认类型打开时,这被序列化为

["com.class.Some",{"one":"two"}]

但是反序列化正在抛出

com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class java.util.HashMap

有什么想法吗?

【问题讨论】:

    标签: java json serialization jackson jackson2


    【解决方案1】:

    @JsonCreator注释你的构造函数:

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    
        Some some = new Some(new HashMap<String, Object>() {{put("a", 1);}});
    
        String json = mapper.writeValueAsString(some);
        System.out.println("serialized  : " + json);
    
        some = mapper.readValue(json, Some.class);
        System.out.println("deserialized: " + some);
    }
    
    // Read only delegating Map
    public static class Some extends AbstractMap<String, Object> {
        private Map<String, Object> delegate;
    
        @JsonCreator
        public Some(Map<String, Object> delegate) {
            this.delegate = Collections.unmodifiableMap(delegate);
        }
    
        @Override
        public Set<Entry<String, Object>> entrySet() {
            return delegate.entrySet();
        }
    }
    

    【讨论】:

    • 这里的问题是 Some 实现了 Map 接口并且有 @Override public Object put(String key, Object value) { throw new UnsupportedOperationException("Is Immutable");所以用你的代码我得到了这个异常。
    • 示例中的map是不可变的,在调用put时抛出UnsupportedOperationException
    【解决方案2】:

    这就是我需要的——自定义反序列化器:

    public class SomeDeserializer extends JsonDeserializer<Some> {
    
        @Override
        public Object deserializeWithType(JsonParser jsonParser, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
            return typeDeserializer.deserializeTypedFromObject(jsonParser, ctxt);
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public Some deserialize(JsonParser jp, DeserializationContext ctxt)
                throws IOException {
            JsonDeserializer<Object> deserializer = ctxt.findRootValueDeserializer(
                    ctxt.getTypeFactory().constructMapType(Map.class, String.class, Object.class));
    
            return new Some((Map) deserializer.deserialize(jp, ctxt, new HashMap<>()));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-05-19
      • 2018-08-24
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      相关资源
      最近更新 更多