为了账号安全,请及时绑定邮箱和手机立即绑定

将通用 JSON 对象解码为多种格式之一

将通用 JSON 对象解码为多种格式之一

幕布斯7119047 2021-09-13 09:43:54
我正在研究 Go 中基于 JSON 的通用消息传递协议。我想要做的是BaseMessage具有一般信息,例如Type,timestamp等。但同时我希望能够为某些类型的数据定义更具体的消息结构。例如:type Message struct {    Type      string `json:type`    Timestamp string `json:timestamp`}type EventMessage struct {    Message    EventType string    EventCreator string    EventData interface{}}我有一组处理程序,为了确定哪个处理程序应该处理消息,我首先将 JSON 解码为通用Message类型以检查该Type字段。对于此示例,我将获取与“事件”消息类型关联的处理程序。当我想将EventMessage类型断言到结构上时,我遇到了问题。以下代码非常粗略,但希望它显示了我尝试处理消息的总体思路。type Handler func(msg Message) Messagehandlers := make(map[string]Handler)var msg Messagedecoder.Decode(&msg)handler := handlers[msg.Type]handler(msg)我曾尝试使用一个,interface{}但 JSON 解码器只是创建了一个地图,然后我无法断言任何一种类型。我已经找到了使其成为可能的解决方法,但它非常丑陋,可能效率不高,而且很可能容易出错。我想让事情简单明了,以便可以轻松维护此代码。是否有一种在 Go 中处理通用 JSON 对象的方法,以便解码后的 JSON 可以是许多结构格式之一?我也想过在Data interface{}主Message结构中的 a中包含更具体的信息,但后来我遇到了无法在接口上断言任何类型的相同问题。必须有更好的方法来处理我刚刚缺少的 JSON 格式。
查看完整描述

1 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

处理此问题的一种方法是使用json.RawMessage字段为消息的固定部分定义一个结构,以捕获消息的变体部分。将 json.RawMessage 解码为特定于变体的类型:


type Message struct {

  Type      string `json:"type"`

  Timestamp string `json:"timestamp"`

  Data      json.RawMessage

}  


type Event struct {

   Type    string `json:"type"`

   Creator string `json:"creator"`

}



var m Message

if err := json.Unmarshal(data, &m); err != nil {

    log.Fatal(err)

}

switch m.Type {

case "event":

    var e Event

    if err := json.Unmarshal([]byte(m.Data), &e); err != nil {

        log.Fatal(err)

    }

    fmt.Println(m.Type, e.Type, e.Creator)

default:

    log.Fatal("bad message type")

}


查看完整回答
反对 回复 2021-09-13
  • 1 回答
  • 0 关注
  • 155 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信