Jackson对以下JSON字符串和相应的Java文件的组合进行反序列化工作很好:
String json = "{'text': 'what is my balance', 'mid': 'D1dexnEBTCefEdRWveEt8A', 'seq': 73}";
import java.io.Serializable;
import java.time.LocalDateTime;
import org.apache.commons.lang3.builder.EqualsBuilder;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@JsonDeserialize(builder = Messages.MessageBuilder.class)
public class Message implements Serializable {
@JsonProperty("id")
public final String id;
@JsonProperty("botId")
public final String botId;
@JsonProperty("userId")
public final String userId;
public final String userIdKey;
public boolean echoText=false;
public String text;
public String timeZone;
public volatile String username;
@JsonProperty("conversationId")
public volatile String conversationId;
public volatile int kaiUserId;
public volatile String token;
public final LocalDateTime inboundReceivedAt;
public volatile LocalDateTime outboundSentAt;
final String key;
private final int _hashCode;
public volatile long lastAccess = System.currentTimeMillis();
public Message(final String pMessageId, final String pUserId, final String pBotId, final String pConversationId, final String pText) {
id = pMessageId;
userId = pUserId;
botId = pBotId;
conversationId = pConversationId;
text = pText;
inboundReceivedAt = LocalDateTime.now();
key = id + "-" + userId + "-" + botId;
userIdKey = userId + "~" + botId;
_hashCode = key.hashCode();
}
void touch() { lastAccess = System.currentTimeMillis(); }
@Override public int hashCode() { return _hashCode; }
@Override public boolean equals(final Object pObject) {
if (!(pObject instanceof Message)) { return false; }
return new EqualsBuilder().append(id, ((Message)pObject).id)
.append(botId, ((Message)pObject).botId)
.append(userId, ((Message)pObject).userId)
.isEquals();
}
private static final long serialVersionUID = 42L;
}
并通过其text
和id
字段填充上面的JSON文件中的值来生成所需的Message对象。
但是,当尝试映射以下JSON字符串时:
String json = "{'entry': [{'messaging': [{'timestamp': 123123123121, "
+ "'message': {'text': 'what is my balance', 'mid': 'D1dexnEBTCefEdRWveEt8A', 'seq': 73}, "
+ "'recipient': {'id': 'kai'}, 'sender': {'id': 'test'}}], "
+ "'id': 'PAGE_ID', 'time': 145645454454}], 'object': 'page'}";
(原始JSON只是其中的一个子集),现在生成的Message
对象在相同的text
和{{1中丢失了值(它们被分配为 null )) }}字段。
以下是我使用的Jackson映射基础结构的所有其他内容:
id
/**
* Jackson backed implementation of {@link Serializer}
*/
public final class JacksonSerializer implements Serializer {
private static ObjectMapper mapper = new ObjectMapper();
static {
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.registerModule(new JavaTimeModule());
mapper.configure(ALLOW_SINGLE_QUOTES, true);
}
/**
* For testing purposes.
*/
static void setMapper(ObjectMapper objectMapper) {
mapper = objectMapper;
}
@Override
public <T> String serialize(T t) {
try {
return mapper.writeValueAsString(t);
} catch (Exception e) {
throw new DatabindException("Serialization error", e);
}
}
@Override
public <T> void serialize(T object, OutputStream outputStream) {
try {
mapper.writeValue(outputStream, object);
} catch (Exception e) {
throw new DatabindException("Serialization error");
}
}
@Override
public <T> void serialize(T object, File file) {
try {
mapper.writeValue(file, object);
} catch (Exception e) {
throw new DatabindException("Serialization error");
}
}
@Override
public <T> T deserialize(String s, Class<T> aClass) {
try {
return mapper.readValue(s, aClass);
} catch (Exception e) {
throw new DatabindException("Deserialization error", e);
}
}
@Override
public <T> T deserialize(InputStream inputStream, Class<T> type) {
try {
return mapper.readValue(inputStream, type);
} catch (Exception e) {
throw new DatabindException("Deserialization error", e);
}
}
@Override
public <T> T deserialize(File file, Class<T> type) {
try {
return mapper.readValue(file, type);
} catch (Exception e) {
throw new DatabindException("Deserialization error", e);
}
}
}
public final class Messages {
private Messages(){}
public static MessageBuilder standard() {
return new MessageBuilder();
}
public final static class MessageBuilder {
@JsonProperty("mid")
String id;
String userId;
String botId;
String conversationId;
@JsonProperty("text")
String text;
public MessageBuilder withId(String id) {
this.id = id;
return this;
}
@JsonProperty("userId")
public MessageBuilder withUserId(String userId) {
this.userId = userId;
return this;
}
@JsonProperty("botId")
public MessageBuilder withBotId(String botId) {
this.botId = botId;
return this;
}
@JsonProperty("conversationId")
public MessageBuilder withConversationId(String conversationId) {
this.conversationId = conversationId;
return this;
}
public MessageBuilder withText(String text) {
this.text = text;
return this;
}
public Message build() {
Message result = null;
result = new Message(id, userId, botId, conversationId, text);
return result;
}
}
public final static class PushMessageBuilder{
}
}
我想知道是否有可能在@Test
public void deserializationTest() {
Serializer serializer = new JacksonSerializer();
String json = "{'entry': [{'messaging': [{'timestamp': 123123123121, "
+ "'message': {'text': 'what is my balance', 'mid': 'D1dexnEBTCefEdRWveEt8A', 'seq': 73}, "
+ "'recipient': {'id': 'kai'}, 'sender': {'id': 'test'}}], "
+ "'id': 'PAGE_ID', 'time': 145645454454}], 'object': 'page'}";
/*String json = "{'text': 'what is my balance', 'mid': 'D1dexnEBTCefEdRWveEt8A', 'seq': 73}";*/
Message message = serializer.deserialize(json, Message.class);
中声明@JsonProperty
的注释值(或者可能有更好的解决方案),使Jackson解析器知道如何遍历JSON。层次结构,并在将其映射到Java对象时仅从中提取必要的项,即:MessageBuilder.java
或具有这种效果的东西。
我正在使用杰克逊2.9.4版
谢谢。