具有复杂键的映射的 JSON 表示形式

2022-09-02 04:01:08

我想将以下(java)数据结构序列化为JSON:

class Machine {
  String name;
  Map<PartDescriptor, Part> parts;
}

class PartDescriptor {
  String group;
  String id;

  hashCode()
  equals()
}

class Part {
  String group;
  String id;
  String description;
  String compat;
  ...
  ...
}

一个的JSON表示形式是什么?Machine

另外(可选),将我指向Java序列化程序/反序列化程序的JSON,它将支持您的表示


答案 1

我会做这样的事情:

{
  "name": "machine name",
  "parts": [
     { "group": "part group", "id": "part id", "description": "...", ... },
     { "group": "part group", "id": "part id", "description": "...", ... },
     // ...
  ]
}

如果每个 Part 的 “id” 是唯一的,则 “parts” 属性可以是对象而不是数组,每个部件的 “id” 充当键。

{
  "name": "machine name",
  "parts": {
     "1st part id": { "group": "part group", "description": "...", ... },
     "2nd part id": { "group": "part group", "description": "...", ... },
     // ...
  }
}

答案 2

您不需要批注或自定义序列化程序。假设您已经拥有 和 中所有字段的 getter,那么真正缺少的就是 on 。如果由于某种原因,您没有 getter 函数,则需要注释感兴趣的字段,以便 Jackson 知道要在序列化输出中包含哪些字段。但是,最好(也更容易)简单地创建 getter。PartMachinetoString()PartDescriptor@JsonProperty

on 应返回要在映射中使用的键。正如另一个答案所建议的那样,您可以简单地连接相关字段:toString()PartDescriptor

@Override
public String toString() {
    return group + "|" + id;
}

然后,当您尝试使用Jackson's序列化时,您将神奇地获得此表单:MachineObjectMapper

{
  "name" : "Toaster",
  "parts" : {
    "Electrical|Descriptor1" : {
      "group" : "Electrical",
      "id" : "Part1",
      "description" : "Heating Element",
      "compat" : "B293"
    },
    "Exterior|Descriptor2" : {
      "group" : "Exterior",
      "id" : "Part2",
      "description" : "Lever",
      "compat" : "18A"
    }
  }
}