java - 使用 JacksonXML 将对象映射到子类
问题描述
我在将 JSON 字符串对象映射到 Java 中的子类时遇到问题。我有一个Message
包含 aMessageType
和 aString
以及消息内容的类。
public class Message {
protected MessageType messageType;
protected String content;
public MessageType getMessageType() {
return messageType;
}
public String getContent() {
return content;
}
public void setMessageType(MessageType messageType) {
this.messageType = messageType;
}
public void setContent(String content) {
this.content = content;
}
}
还有一种特殊的消息,该消息包含一个额外的变量。我将此消息作为该类的子Message
类:
public class QuestionMessage extends Message {
private Question question;
public QuestionMessage() {
}
public Question getQuestion() {
return question;
}
public void setQuestion(Question question) {
this.question = question;
}
}
问题类定义为:
public class Question {
private String question;
private String answerA;
private String answerB;
private String answerC;
private String correctAnswer;
//Getters and setters down here.
}
在我的代码中的其他地方,我收到一个 JSON 字符串,我使用 Jackson'sObjectMapper
将此字符串映射到Message
类:
objectMapper.readValue(jsonString, Message.class);
现在有时 JSON 字符串是一条普通的消息,例如:
{"messageType":"NORMAL","content":"Content string"}
这个 JSON 字符串成功映射到Message
类上并返回一个Message
对象。但是,当我的代码收到特殊消息时,例如:
{"messageType":"NEW_QUESTION", "content":"Content String","question":{"question":"123","answerA":"123","answerB":"123","answerC":"123"}}
不幸的是,我的代码无法将后一个 json 消息映射到QuestionMessage
类上。JacksonXML 是否可以映射到您提供给对象映射器的类(QuestionMessage
)的子类( Message.class
)?
或者这是不可能的,我是否首先必须在传入的 json 字符串中搜索“问题”节点,然后专门调用:
objectMapper.readValue(jsonString, QuestionMessage.class);
代替
objectMapper.readValue(jsonString, Message.class);
解决方案
您可以自定义Deserializer
检查是否存在question
节点。
例如:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
public class MessageDeserializer extends StdDeserializer<Message> {
public MessageDeserializer() {
this(null);
}
public MessageDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Message deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
JsonNode questionNode = node.findValue("question");
if (questionNode != null) {
Question questionMessage = new Question();
...
return questionMessage;
} else {
Message message = new Message();
...
return message;
}
}
}
并使用它:
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Message.class, new MessageDeserializer());
mapper.registerModule(module);
Message readValue = mapper.readValue(json, Message.class);
在这里查看更多详情。
推荐阅读
- javascript - (节点:3340)UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“get”
- java - 如何从stackbuilder启动父活动而不重新创建它?
- c++ - 使用 boost::property_tree 自动失败?
- python - Pydruid对同一个德鲁伊查询的多个查询
- python - 使用鼻子测试时出现“没有这样的文件或目录”错误
- list - 如何在 DART 中将 MAP 转换为 LIST?
- python-3.x - Matplotlib 绘图在另存为 pdf 时失去透明度
- kubernetes - kubernetes.io/csi:预期有效 fsGroupPolicy,收到 nil 值或空字符串
- c++ - boost::asio 内部队列容量
- javascript - 如何在 C# bot 框架中使用 javascript 禁用/启用聊天框中的附件按钮