Я пытаюсь десериализовать коллекцию объектов, которые являются иерархическими и происходят из вызова API, однако мне нужно проанализировать входящий JSON, чтобы решить, как выполнить эту десериализацию.
Я создал собственный десериализатор для объектов соответственно и решаю, как выполнить сериализацию.Однако это вызывает у меня исключение.
Я опущу методы получения и установки для простоты
public abstract class Message implements Serializable {
protected String id = UUID.randomUUID().toString();
protected MessageType type;
protected String to;
protected final static long serialVersionUID = 875082919667906573L;
}
public class SelectContentMessage extends Message {
private SelectContent content;
private final static long serialVersionUID = 875092919667906573L;
}
public class SelectContent implements Serializable {
private String text;
private List<Option> options= new ArrayList<Option>();
}
@JsonDeserialize(using = OptionDeserializer.class)
public abstract class Option implements Serializable {
protected int index;
protected final static long serialVersionUID = 434566339626802052L;
}
@JsonDeserialize(as = SimpleOption.class)
public class SimpleOption extends Option {
private String value = "";
private final static long serialVersionUID = 334566339626702052L;
}
@JsonDeserialize(as = ComplexOption.class)
public class ComplexOption extends Option {
private Value value;
private final static long serialVersionUID = 434566539626702052L;
}
public class Value implements Serializable {
private String title;
}
public class OptionDeserializer extends JsonDeserializer<Option> {
@Override
public Option deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) p.getCodec();
TreeNode node = mapper.readTree(p);
ObjectNode root = (ObjectNode)node;
Class<? extends Option> instanceClass = null;
if (root.has("value") && root.get("value").has("type")) {
String type = root.get("value").get("type").asText();
switch (type) {
case "text/plain":
instanceClass = SimpleOption.class;
default:
instanceClass = ComplexOption.class;
}
return mapper.readValue(p, instanceClass);
}
instanceClass = SimpleOption.class;
return mapper.readValue(p, instanceClass);
}
}
Ниже приведены примеры 3 JSON, которые должны быть десериализованы этими классами:
{"id":"1","to":"1042221589186385@messenger.gw.msging.net","type":"application/vnd.lime.document-select+json","content":{"header":{"type":"application/vnd.lime.media-link+json","value":{"title":"Welcome to mad hatter","text":"Here we have the best hats for your head.","type":"image/jpeg","uri":"http://petersapparel.parseapp.com/img/item100-thumb.png","aspectRatio":"1:1"}},"options":[{"label":{"type":"application/vnd.lime.web-link+json","value":{"text":"Go to our site","uri":"https://petersapparel.parseapp.com/view_item?item_id=100"}}},{"label":{"type":"text/plain","value":"Show stock"},"value":{"type":"application/json","value":{"action":"show-items"}}}]}}
{"to":"553199990000@0mn.io","type":"application/vnd.lime.collection+json","content":{"itemType":"application/vnd.lime.container+json","items":[{"type":"application/vnd.lime.media-link+json","value":{"text":"Welcome to our store!","type":"image/jpeg","uri":"http://www.petshoplovers.com/wp-content/uploads/2014/03/CUIDADOS-B%C3%81SICOS-PARA-CRIAR-COELHOS.jpg"}},{"type":"application/vnd.lime.select+json","value":{"text":"Choose what you need","options":[{"order":1,"text":"See our stock"},{"order":2,"text":"Follow an order"}]}}]}}
{"id":"7577560d-5937-4115-9f82-96c0d705ea5f","type":"application/vnd.lime.select+json","content":{"text":"Choose ?","scope":"immediate","options":[{"text":"App ","previewText":"App","value":"App","index":0,"type":null},{"text":"⤴️ Menu","previewText":"⤴️ Menu","value":"⤴️ Menu","index":1,"type":null}]}}
И я получаю следующую ошибку:
com.fasterxml.jackson.databind.JsonMappingException: com.fasterxml.jackson.databind.node.NullNode cannot be cast to com.fasterxml.jackson.databind.node.ObjectNode (through reference chain: ai.blip.httpintegration.models.messages.SelectContentMessage["content"]->ai.blip.httpintegration.models.messages.SelectContent["options"]->java.util.ArrayList[1])