Reputation: 213
I have a json payload (request payload of a rest api) with a defined schema, but there is one property that can take an array of unknown key value pairs. The value for each property can be of different type like number, string, array, range, date, etc. How do i create a POJO for this property and make deserialization work for the same?
I am currently thinking about writing a custom deserializer for my Property class, where i check the type of value and do some custom logic accordingly.
This looks like a typical requirement. I feel that there should be something available in Jackson or Gson that i am missing. I would love to reuse if it already exist. I looked around in SO, but couldnt find a good answer so far. Any suggestions would be appreciated.
{
"id": 1234,
"name": "test name 1",
"properties": [
{
"key_a": 100
},
{
"key_b": [
"string1",
"string2",
"string3"
]
},
{
"key_c": {
"range": {
"min": 100,
"max": 1000
}
}
}
]
}
I am thinking my POJO for property object would look something like this.
class Property {
private String key;
private Value value;
}
Upvotes: 0
Views: 1233
Reputation: 11
It is possible to use inheritance for that. This is the classes for your example with Jackson
public class Sample {
@JsonProperty(value = "id")
Integer id;
@JsonProperty(value = "name")
String name;
@JsonProperty(value = "properties")
List<Property> properties;
}
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
@JsonSubTypes.Type(value = KeyA.class, name = "key_a"),
@JsonSubTypes.Type(value = KeyB.class, name = "key_b"),
@JsonSubTypes.Type(value = KeyC.class, name = "key_c")
})
public abstract class Property {
}
public class KeyA extends Property{
Integer value;
public KeyA(Integer value) {
this.value = value;
}
@JsonValue
public Integer getValue() {
return value;
}
}
public class KeyB extends Property {
List<String> valueList;
@JsonCreator
public KeyB( List<String> valueList) {
this.valueList = valueList;
}
@JsonValue
public List<String> getValueList() {
return valueList;
}
}
public class KeyC extends Property {
@JsonProperty(value = "range")
Range value;
}
public class Range {
@JsonProperty(value = "min")
Integer min;
@JsonProperty(value = "max")
Integer max;
}
Upvotes: 1
Reputation: 1160
If I understand correctly you want to change to JSON and back. I wrote a small class for my own SpringBoot project, using ObjectMapper
@Component
public final class JsonUtils {
private final ObjectMapper mapper;
@Autowired
public JsonUtils(ObjectMapper mapper) {
this.mapper = mapper;
}
public String asJsonString(final Object object) {
try {
return mapper.registerModule(new JavaTimeModule())
.writeValueAsString(object);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/*
* Customized Objectmapper for reading values compatible with this class' other methods
* @Return the desired object you want from a JSON
* IMPORTANT! -your return object should be a class that has a @NoArgsConstructor-
*/
public Object readValue(final String input, final Class<?> classToRead) {
try {
return mapper
.readValue(input, classToRead);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}`
Perhaps it can be of some use to you.
Upvotes: 0