在 (de)/序列化期间,Jackson 可以使用具有包含在 java.util.Map 中的属性的构建器吗?
Can Jackson use a builder with properties contained in a java.util.Map during (de)/serialization?
这是我的初始设置
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;
}
/**
* 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 = "{'text': 'what is my balance', 'mid': 'D1dexnEBTCefEdRWveEt8A', 'seq': 73}";
Message message = serializer.deserialize(json, Message.class);
我想将构建器更改为以下替代实现,在这种情况下,上述 Jackson 设置将停止查找 JSON 文件与 Jackson 注释之间的关系并映射 Message 对象的所有字段为空。
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;*/
@SuppressWarnings("serial")
private Map<String, String> state = new HashMap<String, String>() {};
@JsonProperty("mid")
public MessageBuilder withId(String id) {
state.put("id", id);
//this.id = id;
return this;
}
public MessageBuilder withUserId(String userId) {
state.put("userId", userId);
//this.userId = userId;
return this;
}
public MessageBuilder withBotId(String botId) {
state.put("botId", botId);
//this.botId = botId;
return this;
}
public MessageBuilder withConversationId(String conversationId) {
state.put("conversationId", conversationId);
//this.conversationId = conversationId;
return this;
}
@JsonProperty("text")
public MessageBuilder withText(String text) {
state.put("text", text);
//this.text = text;
return this;
}
public Message build() {
Message result = null;
result = new Message(state.get("id"),
state.get("userId"),
state.get("botId"),
state.get("conversationId"),
state.get("text"));
/*result = new Message(id, userId, botId, conversationId, text);*/
return result;
}
}
public final static class PushMessageBuilder{
}
}
这是 Jackson 框架支持的东西吗?如果是,需要更改什么?
我使用的是 jackson 版本 2.9.4
提前致谢。
事实证明,此功能已存在于 Jackson 中,而在测试期间另一个问题对我来说已经黯然失色。 MessageBuilder
的以下修改版本展示了所寻求的功能:
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;*/
@SuppressWarnings("serial")
private Map<String, String> state = new HashMap<String, String>() {};
@JsonProperty("mid")
public MessageBuilder withId(String id) {
state.put("id", id);
//this.id = id;
return this;
}
//@JsonProperty("userId")
public MessageBuilder withUserId(String userId) {
state.put("userId", userId);
//this.userId = userId;
return this;
}
//@JsonProperty("botId")
public MessageBuilder withBotId(String botId) {
state.put("botId", botId);
//this.botId = botId;
return this;
}
//@JsonProperty("conversationId")
public MessageBuilder withConversationId(String conversationId) {
state.put("conversationId", conversationId);
//this.conversationId = conversationId;
return this;
}
@JsonProperty("text")
public MessageBuilder withText(String text) {
state.put("text", text);
//this.text = text;
return this;
}
public Message build() {
Message result = null;
result = new Message(state.get("id"),
state.get("userId"),
state.get("botId"),
state.get("conversationId"),
state.get("text"));
//result = new Message(id, userId, botId, conversationId, text);
return result;
}
}
public final static class PushMessageBuilder{
}
}
这是我的初始设置
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;
}
/**
* 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 = "{'text': 'what is my balance', 'mid': 'D1dexnEBTCefEdRWveEt8A', 'seq': 73}";
Message message = serializer.deserialize(json, Message.class);
我想将构建器更改为以下替代实现,在这种情况下,上述 Jackson 设置将停止查找 JSON 文件与 Jackson 注释之间的关系并映射 Message 对象的所有字段为空。
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;*/
@SuppressWarnings("serial")
private Map<String, String> state = new HashMap<String, String>() {};
@JsonProperty("mid")
public MessageBuilder withId(String id) {
state.put("id", id);
//this.id = id;
return this;
}
public MessageBuilder withUserId(String userId) {
state.put("userId", userId);
//this.userId = userId;
return this;
}
public MessageBuilder withBotId(String botId) {
state.put("botId", botId);
//this.botId = botId;
return this;
}
public MessageBuilder withConversationId(String conversationId) {
state.put("conversationId", conversationId);
//this.conversationId = conversationId;
return this;
}
@JsonProperty("text")
public MessageBuilder withText(String text) {
state.put("text", text);
//this.text = text;
return this;
}
public Message build() {
Message result = null;
result = new Message(state.get("id"),
state.get("userId"),
state.get("botId"),
state.get("conversationId"),
state.get("text"));
/*result = new Message(id, userId, botId, conversationId, text);*/
return result;
}
}
public final static class PushMessageBuilder{
}
}
这是 Jackson 框架支持的东西吗?如果是,需要更改什么?
我使用的是 jackson 版本 2.9.4
提前致谢。
事实证明,此功能已存在于 Jackson 中,而在测试期间另一个问题对我来说已经黯然失色。 MessageBuilder
的以下修改版本展示了所寻求的功能:
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;*/
@SuppressWarnings("serial")
private Map<String, String> state = new HashMap<String, String>() {};
@JsonProperty("mid")
public MessageBuilder withId(String id) {
state.put("id", id);
//this.id = id;
return this;
}
//@JsonProperty("userId")
public MessageBuilder withUserId(String userId) {
state.put("userId", userId);
//this.userId = userId;
return this;
}
//@JsonProperty("botId")
public MessageBuilder withBotId(String botId) {
state.put("botId", botId);
//this.botId = botId;
return this;
}
//@JsonProperty("conversationId")
public MessageBuilder withConversationId(String conversationId) {
state.put("conversationId", conversationId);
//this.conversationId = conversationId;
return this;
}
@JsonProperty("text")
public MessageBuilder withText(String text) {
state.put("text", text);
//this.text = text;
return this;
}
public Message build() {
Message result = null;
result = new Message(state.get("id"),
state.get("userId"),
state.get("botId"),
state.get("conversationId"),
state.get("text"));
//result = new Message(id, userId, botId, conversationId, text);
return result;
}
}
public final static class PushMessageBuilder{
}
}