2016-09-18 90 views
0

我有叫ObjectMap的自定義地圖執行如下命令:如何使用jackson ObjectMapper將POJO映射到自定義地圖?

public class ObjectMap extends LinkedHashMap<String, Object> implements Serializable { 
... 
} 

我可以使用傑克遜ObjectMapper如下任何POJO轉換爲該ObjectMap的:

ObjectMapper objectMapper = new ObjectMapper(); 
objectMapper.setVisibility(
      objectMapper.getSerializationConfig(). 
      getDefaultVisibilityChecker(). 
      withFieldVisibility(JsonAutoDetect.Visibility.ANY). 
      withGetterVisibility(JsonAutoDetect.Visibility.NONE). 
      withIsGetterVisibility(JsonAutoDetect.Visibility.NONE) 
); 
ObjectMap objectMap = objectMapper.convertValue(object, new TypeReference<ObjectMap>() {}); 

但問題是,如果我的POJO複雜的領域被映射到一個LinkedHashMap而不是ObjectMap。那麼如何強制ObjectMapper將內部字段映射到ObjectMap而不是LinkedHashMap呢?

回答

0

我想出了以下的解決方案在最後:

public class Document extends LinkedHashMap<String, Object> implements Serializable { 
} 

public class JacksonMapper { 
    private ObjectMapper objectMapper; 

    public <T> Document asDocument(T object) { 
     ObjectMapper objectMapper = getObjectMapper(); 
     JsonNode node = objectMapper.convertValue(object, JsonNode.class); 
     return loadDocument(node); 
    } 

    protected ObjectMapper getObjectMapper() { 
     if (objectMapper == null) { 
      objectMapper = new ObjectMapper(); 
      objectMapper.setVisibility(
        objectMapper.getSerializationConfig(). 
          getDefaultVisibilityChecker(). 
          withFieldVisibility(JsonAutoDetect.Visibility.ANY). 
          withGetterVisibility(JsonAutoDetect.Visibility.NONE). 
          withIsGetterVisibility(JsonAutoDetect.Visibility.NONE) 
      ); 
      objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 
      objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); 
     } 
     return objectMapper; 
    } 

    private Document loadDocument(JsonNode node) { 
     Document document = new Document(); 
     Iterator<Map.Entry<String, JsonNode>> fields = node.fields(); 
     while (fields.hasNext()) { 
      Map.Entry<String, JsonNode> entry = fields.next(); 
      String name = entry.getKey(); 
      JsonNode value = entry.getValue(); 
      document.put(name, loadObject(value)); 
     } 

     return document; 
    } 

    private Object loadObject(JsonNode node) { 
     if (node == null) return null; 
     try { 
      switch (node.getNodeType()) { 
       case ARRAY: 
        return loadArray(node); 
       case BINARY: 
        return node.binaryValue(); 
       case BOOLEAN: 
        return node.booleanValue(); 
       case MISSING: 
       case NULL: 
        return null; 
       case NUMBER: 
        return node.numberValue(); 
       case OBJECT: 
        return loadDocument(node); 
       case POJO: 
        return loadDocument(node); 
       case STRING: 
        return node.textValue(); 
      } 
     } catch (IOException e) { 
      return null; 
     } 
     return null; 
    } 

    private List loadArray(JsonNode array) { 
     if (array.isArray()) { 
      List list = new ArrayList(); 
      Iterator iterator = array.elements(); 
      while (iterator.hasNext()) { 
       Object element = iterator.next(); 
       if (element instanceof JsonNode) { 
        list.add(loadObject((JsonNode) element)); 
       } else { 
        list.add(element); 
       } 
      } 
      return list; 
     } 
     return null; 
    } 
} 

希望這會幫助別人一天。

相關問題