【问题标题】:Dynamic Json string to Java Object [duplicate]动态Json字符串到Java对象[重复]
【发布时间】:2021-03-20 12:12:49
【问题描述】:

如何将此带有动态属性的 JSON 字符串映射到 Java 对象?

{    
    'name' : 'John',
    'lastname': 'Doe',
    'dynamicProperty1': { 'label' : 'size', 'value': 'large'},
    'dynamicProperty2': { 'label' : 'color', 'value': 'blue'},
    'dynamicProperty3': { 'label' : 'height', 'value': 200},
    'dynamicProperty...': { 'label' : 'points', 'value': 300}
}

【问题讨论】:

  • 作为澄清,您似乎暗示属性将遵循特定的命名约定,但假设您可能有任意数量的未知字段名称是否安全? ...'cat': {...}, 'dog':{...}...
  • 无论哪种方式,如果您可以控制此数据模型,为了简单起见,我建议您将所有动态属性移动到一个列表中,而不是像 dynamicProperties: [{...},{...},{...}]
  • @hdost,我无法控制动态属性。这些动态属性可以从 0 到 100。

标签: java json jackson jsonnode


【解决方案1】:

可以使用JsonAnySetter注解:

import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

public class HandleDynamicKeysInJsonApp {

    public static void main(String[] args) throws IOException {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();

        Person person = mapper.readValue(jsonFile, Person.class);
        System.out.println(person);
    }
}

@Data
class Person {
    private String name;

    @JsonProperty("lastname")
    private String lastName;

    private Map<String, Label> labels = new LinkedHashMap<>();

    @JsonAnySetter
    public void addDynamicProperties(String key, Label label) {
        labels.put(key, label);
    }
}

@Data
class Label {
    private String label;
    private Object value;
}

【讨论】:

    【解决方案2】:

    您可以实现一个 Java 类来保存 name、lastName 和 hashmap 以存储动态属性。 示例 -

    public class Person {
       String name;
       String lastName;
       Map<String,Object> dynamicProperty1;
       Map<String,Object> dynamicProperty2;
       Map<String,Object> dynamicProperty3;
    }
    

    或者,如果您有可变数量的动态属性映射(如 cmets 中建议的那样),您可以执行以下操作

    public class Person {
       String name;
       String lastName;
       Map<String,Map<String, Object>> dynamicPropertyMaps;
     }
    

    然后在您的映射器类中,您可以根据 JSON 中的值创建哈希映射并将它们放入 dynamicPropertyMaps 映射中。

    【讨论】:

    • 这不考虑 N 个可能的动态属性。
    • @hdost 如果这是动态的,除了添加地图之外没有其他解决方案。 (即 Map> dynamicPropertyMap)。然后在mapper中,我们可以一张一张地建图,添加到dynamicPropertyMap中
    • 那就是答案。至少作为中介。
    • @DimuthTharakaMenikgama 您可以使用您的建议显示映射器的代码 sn-p 吗?谢谢
    猜你喜欢
    • 2018-01-12
    • 2021-09-04
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多