首页 > 解决方案 > 反序列化 JSON,其中键和值分别存储

问题描述

我有一个 JSON 结构,其中键和值的存储方式如下

[
  {
    "key": "firstName",
    "value": "John"
  },
  {
    "key": "lastName",
    "value": "Smith"
  }
]

我想反序列化数组,以便每个键都是一个属性名称,并分配适当的值。

public class Customer {

  private String firstName;
  private String lastName;

  public String getFirstName() {
    return this.firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return this.lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
}

我曾想过创建一个自定义反序列化器来接受一组客户属性,并根据属性名称手动设置每个属性。我担心这种方法可能会随着添加更多属性而变得脆弱,并且从长远来看是不可维护的。

有谁知道我可能忽略的任何有助于反序列化的 Jackson 注释?

标签: javajsonjacksondeserializationjson-deserialization

解决方案


Jackson将能够反序列化POJOfromJSON ObjectMap. 您有一个迷你地图列表,其中每个迷你地图都包含一个属性。你需要:

  • 将输入有效负载反序列化为List<Map<String, Object>>
  • 将其转换为单个Map对象
  • 转换为Customer实例

简单的例子:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class JsonMiniMapsApp {

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

        ObjectMapper mapper = new ObjectMapper();
        // read as list of maps
        List<Map<String, Object>> entries = mapper.readValue(jsonFile, new TypeReference<List<Map<String, Object>>>() {
        });

        // collect all values to single map
        Map<Object, Object> map = entries.stream().collect(Collectors.toMap(e -> e.get("key"), e -> e.get("value")));

        // convert to POJO
        Customer customer = mapper.convertValue(map, Customer.class);

        System.out.println(customer);
    }
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Customer {

    private String firstName;
    private String lastName;
}

上面的代码打印:

Customer(firstName=John, lastName=Smith)

推荐阅读