[英]How to deserialize property conditionally (on other properties) with Jackson?
[英]Jackson deserialize to a list properties like property_*
我需要序列化一個對象類:
public class DigitalInput {
private String id;
private Date timestamp;
private String matter;
private String comment;
private String channelId;
private List<IndexableProperty> otherProps;
...
}
我收到此JSON:
{
"timestamp":"2015-07-27T10:47:53.765Z",
"matter":"aleatory-1",
"comment":"aleatory comment-1",
"channelId":null,
"property_aleatoryString":"account-1@domain.com",
"property_aleatoryNumber":6.3573580981989274E17,
"property_aleatoryDouble":1.2,
"property_aleatoryDate":"2015-07-27T08:03:01.9892765Z"
}
因此,我需要將otherProps列表內的所有property_ *屬性設置為IndexableProperty
對象。
我創建了一個反序列化器來做到這一點:
public class DigitalInputDeserializer extends JsonDeserializer<DigitalInput> {
@Override
public DigitalInput deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = p.getCodec().readTree(p);
String id = node.get("_id").asText();
Date timestamp = Instant.parse(node.get("timestamp").asText()).toDate();
String matter = node.get("matter").asText();
String description = node.get("comment").asText();
String channelId = node.get("channelId").asText();
... // I don't know how to deserialize property_* like fields in a list
return new DigitalInput(id, channelId, timestamp, matter, description);
}
}
編輯
接下來,我添加了ObjectMapper的配置:
@ApplicationScoped
public class JacksonApplicationResources
{
protected ObjectMapper mapper;
@PostConstruct
protected void initialize_resources() throws IllegalStateException
{
this.mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
// Chanel
module.addDeserializer(Channel.class, new ChannelDeserializer());
module.addSerializer(Channel.class, new ChannelSerializer());
module.addDeserializer(DigitalInput.class, new DigitalInputDeserializer());
module.addSerializer(DigitalInput.class, new DigitalInputSerializer());
this.mapper.registerModule(module);
}
public ObjectMapper getMapper() {
return this.mapper;
}
}
必須放置以下代碼,而不是“ ... //我不知道...”:
List<IndexableProperty> list = new ArrayList();
Iterator<Map.Entry<String, JsonNode>> iterator = node.fields();
while(iterator.hasNext()) {
Map.Entry<String, JsonNode> entry = iterator.next();
String key = entry.getKey();
if (key.startsWith("property_")) {
String propertyKey = StringUtils.substringAfter(key, "property_");
IndexableProperty prop = new IndexableProperty(propertyKey, entry.getValue().asText());
list.add(prop);
}
}
// 'list' is initialized with props
請記住以下幾點:
entry.getValue()
,因為JsonNode
確切類型是未知的(可以使用if-instanceof
塊,但是將名稱映射為更好的方法) 您還可以考慮使用@JsonAnySetter批注實現相同的功能,而無需自定義反序列化。
這是一個完整的示例:
public class JacksonAnySetter {
private static final String JSON = "{\n"
+ " \"timestamp\":\"2015-07-27T10:47:53.765Z\",\n"
+ " \"matter\":\"aleatory-1\",\n"
+ " \"comment\":\"aleatory comment-1\",\n"
+ " \"channelId\":null,\n"
+ " \"property_aleatoryString\":\"account-1@domain.com\",\n"
+ " \"property_aleatoryNumber\":6.3573580981989274E17,\n"
+ " \"property_aleatoryDouble\":1.2,\n"
+ " \"property_aleatoryDate\":\"2015-07-27T08:03:01.9892765Z\"\n"
+ "}";
public static class IndexableProperty {
public final String key;
public final String value;
public IndexableProperty(final String key, final String value) {
this.key = key;
this.value = value;
}
@Override
public String toString() {
return "IndexableProperty{" +
"key='" + key + '\'' +
", value='" + value + '\'' +
'}';
}
}
public static class DigitalInput {
@JsonProperty
private String id;
@JsonProperty
private Date timestamp;
@JsonProperty
private String matter;
@JsonProperty
private String comment;
@JsonProperty
private String channelId;
private List<IndexableProperty> otherProps = new ArrayList<>();
@JsonAnySetter
public void setOtherProps(final String key, final String value) {
this.otherProps.add(new IndexableProperty(key, value));
}
@Override
public String toString() {
return "DigitalInput{" +
"id='" + id + '\'' +
", timestamp=" + timestamp +
", matter='" + matter + '\'' +
", comment='" + comment + '\'' +
", channelId='" + channelId + '\'' +
", otherProps=" + otherProps +
'}';
}
}
public static void main(String[] args) throws IOException {
final ObjectMapper objectMapper = new ObjectMapper();
System.out.println(objectMapper.readValue(JSON, DigitalInput.class));
}
}
輸出:
DigitalInput{id='null', timestamp=Mon Jul 27 14:47:53 MSK 2015, matter='aleatory-1', comment='aleatory comment-1', channelId='null', otherProps=[IndexableProperty{key='property_aleatoryString', value='account-1@domain.com'}, IndexableProperty{key='property_aleatoryNumber', value='6.3573580981989274E17'}, IndexableProperty{key='property_aleatoryDouble', value='1.2'}, IndexableProperty{key='property_aleatoryDate', value='2015-07-27T08:03:01.9892765Z'}]}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.