使用jackson自动解析非固定格式json

前段时间做了一个即时通讯项目,用的是腾讯云的IM服务,客户端内嵌腾讯云IM sdk,发消息的时候消息先发送到腾讯云服务器,腾讯云服务器再回调我们的接口,完成消息入库。问题来了,腾讯云的消息体内格式不是固定的,我们如何将数据封装到Java类里面去呢? 答案就是用jackson
腾讯云消息格式参见消息格式
代码中的@Getter等注解都是lombok注解。
腾讯云消息格式大致如下:

{
    //为了方便起见,json中只保留MsgBody,实际数据中还有很多与MsgBody平级的字段
    "MsgBody": [
        {
            "MsgType": "TIMTextElem", 
            "MsgContent": {
                "Text": "hello"
            }
        }, 
        {
            "MsgType": "TIMFaceElem", 
            "MsgContent": {
                "Index": 1, 
                "Data": "content"
            }
        }, 
        {
            "MsgType": "TIMTextElem", 
            "MsgContent": {
                "Text": "world"
            }
        }
    ]
}

MsgBody是消息数据体,当里面只有一个对象的时候是单条消息,如果有多个对象的时候是组合消息。比如上面的json格式就是一个文本+表情+文本的组合消息。为方便说明,本文都以文本消息和表情消息为例说明
针对腾讯云的每一种消息,我们都定义了一个消息格式类。
我们将MsgBody里面每一个对象抽象成一个类,对应的类定义如下:

@ToString
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class TimMsgElement implements BaseVO {

    @JsonProperty("MsgContent")
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "MsgType", visible = true)
    private TimMsgElementContent msgContent;

    @JsonProperty("MsgType")
    private String msgType;

}

下面我们为每一种MsgContent定义一个类
MsgType为TIMTextElem的MsgContent类如下:

@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
@ToString
public class TimTextMsgElementContent extends TimMsgElementContent {
    @JsonProperty("Text")
    private String text;
}

MsgType为TIMFaceElem的MsgContent类如下:

@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
@ToString
public class TimFaceMsgElementContent extends TimMsgElementContent {

    /**
     * 表情索引,用户自定义。
     */
    @JsonProperty(value = "Index")
    private Integer index;

    /**
     * 额外数据
     */
    @JsonProperty(value = "Data")
    private String data;
}

父类TimMsgElementContent的定义如下:

@Data
@JsonSubTypes({
        @JsonSubTypes.Type(name = "TIMTextElem", value = TimTextMsgElementContent.class),
        @JsonSubTypes.Type(name = "TIMFaceElem", value = TimFaceMsgElementContent.class),
})
public class TimMsgElementContent implements Serializable {

}

@JsonTypeInfo注解用于定义根据哪个字段将数据封装到哪个类中。这里用MsgType字段
@JsonSubTypes注解用于定义MsgType与MsgContent的关系。如此jackson便知道当MsgType=TIMTextElem的时候应该用TimTextMsgElementContent去封装MsgContent数据,当MsgType=TIMFaceElem的时候应该用TimFaceMsgElementContent去封装MsgContent数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值