使用Jackson/ Gson API将Map〈String,Set>转换为POJO

kiayqfof  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(204)

我使用的是第三方API,返回的数据为Map〈String,Set〈?〉〉,格式为JSON,其中key是一个String,与类变量相同,Set包含相关的值,该值将是String,即使是Set,也只需要一个值。
现在,一种方法是循环Map并使用Reflection填充POJO。
我想知道Jackson/ Gson API是否可以用于填充POJO。我尝试了两种方法,但POJO中没有填充值。

JSON:
{
    "Id": [
        "345"
    ],
    "Name": [
        "John"
    ]
}

POJO:
public class Employee implements Serializable {
  private String id;
  private String name;

  // getter / setter
}

My Code:

Map<String, Set<?>> data = someObject.getDataSet();

ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Employee employee = mapper.convertValue(data, Employee.class);
System.out.println(employee);

更新:我尝试了以下操作,但POJO仍然为空

Map<String, Set<?>> data = someObject.getDataSet();

Map<String, String> map = data.entrySet().stream()
        .filter(entry -> entry.getValue() != null)
        .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().iterator().next().toString()));

Employee employee = null;

ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Employee = mapper.convertValue(map, Employee.class);
System.out.println(employee);

Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(map);
Employee = gson.fromJson(jsonElement, Employee.class);
System.out.println(employee);
9lowa7mx

9lowa7mx1#

您的问题似乎是特定的,我认为没有内置的方法来实现这一点,您可以使用Jackson加载整个树,然后只将节点Map到POJO
例如:

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json);
Iterator<JsonNode> ids = root.get("Id").iterator();
Iterator<JsonNode> names = root.get("Names").iterator();

while (ids.hasNext()) {
    String id = ids.next().asText();
    String name = null;
    if (names.hasNext()) {
        name = names.next().asText();
    }
    employees.add(new Employee(id, name));
}

另一种方式:

JsonNode root = objectMapper.readTree(json);

Map<String, Iterator<JsonNode>> iterators = new HashMap<>();
root.fieldNames().forEachRemaining(name -> iterators.put(name, root.get(name).iterator()));

List<Map<String, String>> allAttributes = new ArrayList<>();
while (true) {
    Map<String, String> attributes = new HashMap<>();
    for (Map.Entry<String, Iterator<JsonNode>> e : iterators.entrySet()) {
        if (e.getValue().hasNext()) {
            attributes.put(e.getKey(), e.getValue().next().asText());
        }
    }
    if (attributes.size() != 0) {
        allAttributes.add(attributes);
    } else {
        break;
    }
}

List<Employee> employees = allAttributes.stream()
    .map(this::mapToEmployee)
    .collect(Collectors.toList());

然后添加将属性值Map到POJO方法
您也可以在没有Map方法的情况下执行此操作:

JsonNode root = mapper.readTree(json);

Map<String, Iterator<JsonNode>> iterators = new HashMap<>();
root.fieldNames().forEachRemaining(name -> iterators.put(name, 
root.get(name).iterator()));

List<JsonNode> nodes = new ArrayList<>();
while (true) {
    boolean hasNext = false;
    ObjectNode node = mapper.createObjectNode();
    for (Map.Entry<String, Iterator<JsonNode>> e : iterators.entrySet()) {
        if (e.getValue().hasNext()) {
            hasNext = true;
            node.put(e.getKey(), e.getValue().next().asText());
        }
    }
    if (hasNext) {
        nodes.add(node);
    } else {
        break;
    }
}

List<Employee> employees = new ArrayList<>();
nodes.forEach(node -> {
    try {
        employees.add(mapper.treeToValue(node, Employee.class));
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
});

相关问题