簡體   English   中英

傑克遜反序列化到諸如property_ *的列表屬性

[英]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

請記住以下幾點:

  1. 我使用Apache Commons Lang提取子字符串。
  2. 您應該決定如何處理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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM