JSON Представление карты со сложным ключом
Я хочу сериализовать в JSON следующую структуру данных (java):
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
?
Также (необязательно), укажите мне на сериализатор/десериализатор JSON на Java, который будет поддерживать ваше представление
Ответы
Ответ 1
Я бы сделал что-то вроде:
{
"name": "machine name",
"parts": [
{ "group": "part group", "id": "part id", "description": "...", ... },
{ "group": "part group", "id": "part id", "description": "...", ... },
// ...
]
}
Если "id" для каждой части уникален, то свойство "parts" может быть объектом вместо массива с "id" каждой части, служащей в качестве ключа.
{
"name": "machine name",
"parts": {
"1st part id": { "group": "part group", "description": "...", ... },
"2nd part id": { "group": "part group", "description": "...", ... },
// ...
}
}
Ответ 2
Вам не нужны аннотации или пользовательские сериализаторы. Предполагая, что у вас уже есть геттеры для всех полей в Part
и Machine
, все, что действительно отсутствует, это toString()
on PartDescriptor
. Если по какой-то причине у вас нет функций getter, вам нужно будет аннотировать интересующие поля с помощью @JsonProperty
, чтобы Джексон знал, какие поля включать в сериализованный вывод. Однако предпочтительно (и проще) просто создавать геттеры.
toString()
на PartDescriptor
должен вернуть ключ, который вы хотите использовать в своем сопоставлении. Как следует из другого ответа, вы можете просто объединить соответствующие поля:
@Override
public String toString() {
return group + "|" + id;
}
Затем вы будете магически получать эту форму при попытке сериализации Machine
с помощью Jackson ObjectMapper
:
{
"name" : "Toaster",
"parts" : {
"Electrical|Descriptor1" : {
"group" : "Electrical",
"id" : "Part1",
"description" : "Heating Element",
"compat" : "B293"
},
"Exterior|Descriptor2" : {
"group" : "Exterior",
"id" : "Part2",
"description" : "Lever",
"compat" : "18A"
}
}
}
Ответ 3
Я бы сделал это. Ключ parts
объекта верхнего уровня будет JSONArray
JSONObject
, у которого есть key
и value
. key
будет объектом, который является вашим PartDescriptor
, а value
будет вашим Part
.
{
"name":"theName",
"parts":[
{
"key":{
"group":"theGroup",
"id":"theId"
},
"value":{
"group":"theGroup",
"id":"theId",
"description":"theDescription",
"compat":"theCompat",
...
}
},
...
]
}
Ответ 4
Предполагая, что группа + id дает уникальную комбинацию и что ":" является допустимым разделителем:
{
"name": "machine name",
"parts": {
"somegroup:01465": {
"group":"somegroup",
"id": "01465",
...
},
"othergroup:32409": {
"group":"othergroup",
"id": "32409",
...
}
}
}
Ответ 5
Он может отображаться как следующая таблица:
<table class="machine" name="">
<tr>
<th class="partdescriptor" colspan="2">
<th class="part" colspan="4">
</tr>
<tr>
<td class="partdescriptor group"></td>
<td class="partdescriptor" id=""></td>
<td class="part group"></td>
<td class="part" id=""></td>
<td class="description"></td>
<td class="compat"></td>
</tr>
</table>
Разметка распадается на следующий объект JSON из-за отсутствия метаданных через атрибуты:
{
"HTMLTableElement":
[
{
"classname": "machine",
"name": ""
},
{
"HTMLTableRowElement":
[
{
"HTMLTableCellElement": {"classname":"partdescriptor","colspan":2}
},
{
"HTMLTableCellElement": {"classname":"part","colspan":4}
}
]
},
{
"HTMLTableRowElement":
[
{
"HTMLTableCellElement": {"classname":"partdescriptor group"}
},
{
"HTMLTableCellElement": {"classname":"partdescriptor","id":""}
},
{
"HTMLTableCellElement": {"classname":"part","id":""}
},
{
"HTMLTableCellElement": {"classname":"description"}
},
{
"HTMLTableCellElement": {"classname":"compat"}
}
]
}
]
}
В качестве альтернативы Unicode может упростить отображение:
{"name":"","[{\u0022group\u0022:\u0022\u0022},{\u0022id\u0022:\u0022\u0022}]":
[
{"group":""},
{"id":""},
{"description":""},
{"compat":""}
]
}
Что может быть сжато:
JSON.stringify({"name":"","[{\u0022group\u0022:\u0022\u0022},{\u0022id\u0022:\u0022\u0022}":[{"group":""},{"id":""},{"description":""},{"compat":""}]})
для создания:
"{\"name\":\"\",\"[{\\\"group\\\":\\\"\\\"},{\\\"id\\\":\\\"\\\"}]\":[{\"group\":\"\"},{\"id\":\"\"},{\"description\":\"\"},{\"compat\":\"\"}]}"
который можно разобрать:
JSON.parse("{\"name\":\"\",\"[{\\\"group\\\":\\\"\\\"},{\\\"id\\\":\\\"\\\"}]\":[{\"group\":\"\"},{\"id\":\"\"},{\"description\":\"\"},{\"compat\":\"\"}]}")
для создания литерала объекта:
({name:"", '[{"group":""},{"id":""}]':[{group:""}, {id:""}, {description:""}, {compat:""}]})
Ссылки