java - 使用具有字段依赖关系的 Jackson 反序列化 JSON

标签 java android json jackson

在我们的项目中,我们使用 Jackson 解析 JSON。我们通过字段channelId设置字段saved。问题是 channelId 字段的解析晚于 saved。所以此时我们要设置字段saved字段channelId为null。我们如何在 JSON 反序列化中设置字段依赖,以便在 channelId 之后设置字段 saved

这是我们 JSON 数据的一部分:

"message":{  
            "data":{  
               "text":"Some text"
            },
            "saved_by":[  
               2715,
               1234
            ],
            "some_boolean_field":false,
            "channel_id":8162
           }

这是我们的实体类:

@JsonIgnoreProperties(ignoreUnknown = true)
@org.parceler.Parcel(org.parceler.Parcel.Serialization.BEAN)

public class Message {

    @JsonProperty("channel_id")
    protected long channelId;

    protected boolean saved;

    @JsonSetter("saved_by")
    public void setSavedBy(Set<Long> savedBy) {
        saved = savedBy.contains(getUserIdByChannelId(channelId));
    }

    public long getChannelId() {
        return channelId;
    }

    public void setChannelId(long channelId) {
        this.channelId = channelId;
    }

    public boolean isSaved() {
        return saved;
    }

    public void setSaved(boolean saved) {
        this.saved = saved;
    }

    public void setData(JsonNode data) throws JsonProcessingException {
        JsonNode textNode = data.get("text");
        text = textNode != null ? textNode.asText() : "";

        components = new ArrayList<>();
        JsonNode mediaNode = data.get("media");
        if (mediaNode != null) {
            MessageComponent[] parsedComponents = AppSession.getInstance().getObjectMapper().treeToValue(mediaNode, MessageComponent[].class);
            List<MessageComponent> components = Arrays.asList(parsedComponents).subList(0, parsedComponents.length < 4 ? parsedComponents.length : 4);

            this.components.addAll(components);
        }

        mediaCount = components.size();
    }

    }

完整的 JSON:

{  
   "data":{  
      "serial":66,
      "updated_entity":"bookmark",
      "bookmark":{  
         "message":{  
            "data":{  
               "text":"hello"
            },
            "counted_serial":748,
            "saved_by":[  
               26526,
               27758
            ],
            "type":"UserMessage",
            "is_reviewed":false,
            "channel_id":8128,
            "id":2841531,
            "replied_message_data":null,
            "is_blocked":false,
            "is_deleted":false,
            "updated_at":"2016-11-21T05:59:52.471Z",
            "spam_reported_by":[  

            ],
            "created_at":"2016-11-19T15:40:17.027Z",
            "uuid":"0b6ba58e-f5e1-4ee5-a9da-041dfc2c85cd",
            "liked_by":[  

            ],
            "user":{  
               "last_name":"M",
               "id":4537,
               "first_name":"John",
               "is_deleted":false,
               "avatar_thumb":"https:\/\/cdn.site.org\/uploads\/99ef4d68-6eaf-4ba6-aafa-74d1cf895d71\/thumb.jpg"
            },
            "serial":934
         },
         "id":6931,
         "created_at":"2016-11-21T05:59:52.459Z",
         "is_deleted":false,
         "updated_at":"2016-11-21T05:59:52.459Z"
      }
   },
   "type":"action_performed"
}

最佳答案

这有点 hackish,但是通过将 Message 类设为自己的反序列化构建器,您可以获得一种“准备 bean 创建”事件,在该事件中您可以访问所有属性.

我的建议是您尝试以下操作:

@JsonDeserialize(builder = Message.class)
public class Message {

    ...

    @JsonSetter("saved_by")
    public void setSavedBy(Set<Long> savedBy) {
        // Merely store the value for later use.
        this.savedBy = savedBy;
    }

    ...

    public Message build() {
        // Calculate value of "saved" field.
        this.saved = this.savedBy.contains(getUserIdByChannelId(this.channelId));
        return this;
    }

    // Handling the added challenge.
    @JsonProperty("data") 
    public void setData(JsonNode data) throws JsonProcessingException {
       ...
    }
}

上面利用了JsonPOJOBuilder注释的默认设置,即buildMethodName的默认值为build

关于java - 使用具有字段依赖关系的 Jackson 反序列化 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40713032/

相关文章:

java - 当不使用参数和主体时,retrofit 的错误请求,这怎么可能?

java - 列表分区

osgi - 如何定义最低 GRE 要求(1.5 _ 或更高 _)?

android - Activitymanager 在终止进程后启动 Activity 进程

ios - 将自定义对象序列化为包含NSMutableArray的JSON

java - 模板解析时发生错误(模板: "class path resource [templates/addWunsch.html]")

java - android tabhost 的 Activity 生命周期

Android:使用 Shape Drawable 的多虚线背景

json - 将对象转换为可编码对象失败

android - 目标主机错误,同时发布 HTTP 请求