簡體   English   中英

如何使用傑克遜ObjectMapper將POJO映射到自定義Map?

[英]How to map a POJO to a custom Map using jackson ObjectMapper?

我有一個名為ObjectMap的自定義地圖實現,如下所示:

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

我可以使用jackson 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中?

我終於想出了以下解決方案:

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;
    }
}

希望有一天能對某人有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM