Из библиотеки Jackson
вы можете использовать аннотации JsonTypeInfo
и JsonSubTypes
.Они обрабатывают обработку полиморфного типа:
@JsonTypeInfo
используется для указания деталей того, какая информация о типе включена в сериализацию @JsonSubTypes
используется для указания подтипов аннотированныхтип @JsonTypeName
используется для определения имени логического типа, используемого для аннотированного класса
Ваш пример подходит для этого решения, за исключением корневого объекта, который больше похож на простой класс POJO
.В вашем случае мы должны создать структуру типов, которая поможет работать с этими 3 типами: string
, date
, map
:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = StringValue.class, name = "string"),
@JsonSubTypes.Type(value = DateValue.class, name = "date"),
@JsonSubTypes.Type(value = MapValue.class, name = "map")
})
abstract class HasValue<T> {
protected T value;
public HasValue() {
this(null);
}
public HasValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
@Override
public String toString() {
return getClass().getSimpleName() + "{" +
"value=" + value +
"}";
}
}
class StringValue extends HasValue<String> {
public StringValue() {
this(null);
}
public StringValue(String value) {
super(value);
}
}
class DateValue extends HasValue<String> {
public DateValue(String value) {
super(value);
}
public DateValue() {
this(null);
}
}
class MapValue extends HasValue<Map<String, HasValue>> {
public MapValue(Map<String, HasValue> value) {
super(value);
}
public MapValue() {
this(new LinkedHashMap<>());
}
public void put(String key, HasValue hasValue) {
this.value.put(key, hasValue);
}
}
Теперь нам нужно ввести POJO
для корневого значения.Это может выглядеть как показано ниже, но вы можете добавить геттеры / сеттеры, если хотите.Для приведенного ниже примера будет достаточно кода:
class Root {
public HasValue firstObject;
public HasValue secondObject;
public HasValue thirdObject;
public HasValue fourthObject;
@Override
public String toString() {
return "Root{" +
"firstObject=" + firstObject +
", secondObject=" + secondObject +
", thirdObject=" + thirdObject +
", fourthObject=" + fourthObject +
'}';
}
}
Теперь мы наконец можем попытаться сериализовать и десериализовать эти объекты:
MapValue customerName = new MapValue();
customerName.put("customerName", new StringValue("customerValue"));
MapValue innerMap = new MapValue();
innerMap.put("anotherObj1", new StringValue("TEST"));
innerMap.put("anotherObj2", new DateValue("01/12/2018"));
innerMap.put("anotherObj3", new DateValue("31/01/2018"));
MapValue fourthObject = new MapValue();
fourthObject.put("firstObject", innerMap);
Root root = new Root();
root.firstObject = new StringValue("productValue");
root.secondObject = new StringValue("statusValue");
root.thirdObject = customerName;
root.fourthObject = fourthObject;
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
System.out.println(json);
System.out.println(mapper.readValue(json, Root.class));
Печатает код Aboce JSON
:
{
"firstObject" : {
"type" : "string",
"value" : "productValue"
},
"secondObject" : {
"type" : "string",
"value" : "statusValue"
},
"thirdObject" : {
"type" : "map",
"value" : {
"customerName" : {
"type" : "string",
"value" : "customerValue"
}
}
},
"fourthObject" : {
"type" : "map",
"value" : {
"firstObject" : {
"type" : "map",
"value" : {
"anotherObj1" : {
"type" : "string",
"value" : "TEST"
},
"anotherObj2" : {
"type" : "date",
"value" : "01/12/2018"
},
"anotherObj3" : {
"type" : "date",
"value" : "31/01/2018"
}
}
}
}
}
}
И toString
представление:
Root{firstObject=StringValue{value=productValue}, secondObject=StringValue{value=statusValue}, thirdObject=MapValue{value={customerName=StringValue{value=customerValue}}}, fourthObject=MapValue{value={firstObject=MapValue{value={anotherObj1=StringValue{value=TEST}, anotherObj2=DateValue{value=01/12/2018}, anotherObj3=DateValue{value=31/01/2018}}}}}}
Вы можете легко управлять выводом, добавляя / удаляя любой тип HasValue
экземпляра.
Для получения дополнительной информации см .:
- аннотации Джексона
- Джексон Мавен