如何将Java类转换为Map< String,String>并使用杰克逊将非字符串成员转换为json? [英] How to convert Java class to Map<String, String> and convert non-string members to json using jackson?

查看:51
本文介绍了如何将Java类转换为Map< String,String>并使用杰克逊将非字符串成员转换为json?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java中有一些要转换为Map<String, String>的类.问题是,我的Java类的任何没有明显String表示形式的字段(集合,其他类)都应转换为json字符串.

I have some class in Java that I want to convert to a Map<String, String>. The catch is that any fields of my java class that don't have an obvious String representation (collections, other classes) should be converted to json strings.

这是一个例子:

@Data
@AllArgsConstructor
class MyClass {
    String field1;
    Long field2;
    Set<String> field3;
    OtherClass field4;
}

@Data
@AllArgsConstructor
class OtherClass {
    String field1;
    String field2;
}

ObjectMapper mapper = new ObjectMapper();
MyClass myClass = new MyClass("value", 
                              123L, 
                              Sets.newHashSet("item1", "item2"),
                              new OtherClass("value1", "value2"));
Map<String, String> converted =
        mapper.convertValue(myClass, new TypeReference<Map<String, String>>(){});

此时,converted应该如下所示:

"field1" -> "value"
"field2" -> "123"
"field3" -> "[\"item1\", \"item2\"]"
"field4" -> "{\"field1\":\"value1\",\"field2\":\"value2\"}"

相反,尝试使用除java.lang.IllegalArgumentException: Can not deserialize instance of java.lang.String out of START_ARRAY token的异常对Set进行反序列化时,对mapper.convertValue的调用失败.

Instead, the call to mapper.convertValue fails when trying to deserizlize the Set with the exception java.lang.IllegalArgumentException: Can not deserialize instance of java.lang.String out of START_ARRAY token.

我是否可以使用MyClass注释任何特殊的配置,或者配置ObjectMapper以使其按我希望的方式工作的方式?

Are there any special configurations I can annotate MyClass with or ways to configure the ObjectMapper to make this work the way I want it to?

推荐答案

这是一种实现方法.

private static final ObjectMapper mapper = new ObjectMapper();

public Map<String, String> toMap(Object obj) {
    // Convert the object to an intermediate form (map of strings to JSON nodes)
    Map<String, JsonNode> intermediateMap = mapper.convertValue(obj, new TypeReference<Map<String, JsonNode>>() {});

    // Convert the json nodes to strings
    Map<String, String> finalMap = new HashMap<>(intermediateMap.size() + 1); // Start out big enough to prevent resizing
    for (Map.Entry<String, JsonNode> e : intermediateMap.entrySet()) {
        String key = e.getKey();
        JsonNode val = e.getValue();

        // Get the text value of textual nodes, and convert non-textual nodes to JSON strings
        String stringVal = val.isTextual() ? val.textValue() : val.toString();

        finalMap.put(key, stringVal);
    }

    return finalMap;
}

如果要转换Map< String,String>回到原来的课...

And if you want to convert the Map<String, String> back to the original class...

public static <T> T fromMap(Map<String, String> map, Class<T> clazz) throws IOException {
    // Convert the data to a map of strings to JSON nodes
    Map<String, JsonNode> intermediateMap = new HashMap<>(map.size() + 1); // Start out big enough to prevent resizing
    for (Map.Entry<String, String> e : map.entrySet()) {
        String key = e.getKey();
        String val = e.getValue();

        // Convert the value to the right type of JsonNode
        JsonNode jsonVal;
        if (val.startsWith("{") || val.startsWith("[") || "null".equals(val)) {
            jsonVal = mapper.readValue(val, JsonNode.class);
        } else {
            jsonVal = mapper.convertValue(val, JsonNode.class);
        }

        intermediateMap.put(key, jsonVal);
    }

    // Convert the intermediate map to an object
    T result = mapper.convertValue(intermediateMap, clazz);

    return result;
}

这篇关于如何将Java类转换为Map&lt; String,String&gt;并使用杰克逊将非字符串成员转换为json?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆