在将JSON反序列化为Java对象时映射动态字段名称

时间:2018-02-02 20:05:24

标签: java json jackson deserialization objectmapper

我有一个有趣的问题,我想解决。这是我正在解析我们与之交互的平台之一的响应。响应根据用户而变化。

对于用户A说,我有以下JSON:

{
 "userId": "AA001",
 "AA001_Name": "Username",
 "AA001_Email": "user@gmail.com",
 "AA001_Phone": "000-000-0000"
}

对于用户B,我有:

{ 
  "userId" : "AA002",
  "AA002_Name" : "Username",
  "AA002_Email" : "user@gmail.com",
  "AA002_Phone" : "000-000-0000"
}

现在,在反序列化时,我想将它们映射到以下对象,忽略json附带的字段名称:

class User {
  private String userId,
  private String name,
  private String email,
  private String phone
}

很容易映射userId,因为它也是JSON中的字段,但是自定义字段呢?

现在,我无法使用@JsonProperty,因为该字段的名称会根据用户动态更改。

有什么办法可以实现吗? 请注意,我可能有几个这样的自定义对象,如部门,组织等,平台以这种方式返回数据,这意味着密钥具有附加的用户特定信息。

感谢任何帮助。我对此很不满意。

2 个答案:

答案 0 :(得分:1)

我认为你做得比使用@JsonCreator更好:

class User {

    private String userId;
    private String name;
    private String email;
    private String phone;

    @JsonCreator
    public User(Map<String, Object> map) {
        this.userId = (String) map.get("userId");
        map.entrySet().stream()
            .filter(e -> e.getKey().endsWith("_Name"))
            .findFirst()
            .ifPresent(e -> this.name = (String) e.getValue());
        // repeat for other fields
    }

    // getters & setters (if needed)
}

您可以在地图的条目集上为传统流更改流,以优化性能。

答案 1 :(得分:0)

您不能按原样使用@JSONProperty,但如果在反序列化JSON之前重新格式化键会怎么样? I.E

  String key = "AA001_Name"
  String[] key = key.split("_") 
  key[0] = "AA001"
  key[1] = "Name"
  //Use key[1] as the new field name

对每个键执行此操作,使用正确的字段名称创建新的JSON对象,然后对其进行反序列化。