【问题标题】:go un/marshal struct as json去 un/marshal 结构为 json
【发布时间】:2020-05-22 14:57:30
【问题描述】:

我需要将 json rpc 消息包装在一个 go 结构中 这是我的第一个想法,它适用于这样的传出消息

// Message wrapper
type Message struct {
    ID      *string      `json:"id,omitempty"`
    JSONRPC string       `json:"jsonrpc"`
    Method  *string      `json:"method,omitempty"`
    Params  *interface{} `json:"params,omitempty"`
    Result  *interface{} `json:"result,omitempty"`
}

// NewNotification creates a RPC Notification
func NewNotification(method string, params interface{}) Message {

    m := Message{}
    m.JSONRPC = "2.0"
    m.Method = &method
    m.Params = &params

    return m

}

type Test struct {
        A string `json:"a"`
        B string `json:"b"`
}

t := Test{"abc", "def"}

m := NewNotification("testMethod", t)

socket.WriteJSON(m)

但是现在对于接收方向,我遇到了问题 Params *interface{} 声明。

我通过Method 字段识别Params 有效负载类型并希望 将Params 解组到该结构...但因此我需要类型 json.RawMessage Params 让这个工作。

我不想定义 MessageInMessageOut 结构!

m := Message{}
socket.ReadJSON(m)

t := Test{}

json.Unmarshal(m.Params, &t)

【问题讨论】:

  • 尝试预先声明一个目标类型的实例:var mesg json.RawMessage; var params interface{} = &mesg; Test{Params: &params}

标签: go marshalling


【解决方案1】:

您应该使用json.RawMessage 作为参数和结果字段的类型。这将延迟这些字段的解码,直到您知道接收端的方法是什么。查看文档和示例:这是相同的用例:https://golang.org/pkg/encoding/json/#RawMessage

【讨论】:

  • 是的,没关系,但我必须手动编组参数/结果以发送和接收方向
【解决方案2】:

好的,这个想法有一个MessageInMessageOut 结构,但它们共享Message 的共同部分。这样就可以让 WriteJson 在发送方向上进行编组。当方法和假定的负载类型已知时,接收解组必须手动完成。

// Message wrapper
type Message struct {
    ID      *string `json:"id,omitempty"`
    JSONRPC string  `json:"jsonrpc"`
    Method  *string `json:"method,omitempty"`
}

// MessageIn wrapper
type MessageIn struct {
    Message
    Params *json.RawMessage `json:"params,omitempty"`
    Result *json.RawMessage `json:"result,omitempty"`
}

// MessageOut wrapper
type MessageOut struct {
    Message
    Params *interface{} `json:"params,omitempty"`
    Result *interface{} `json:"result,omitempty"`
}

// NewNotification creates a RPC Notification
func NewNotification(method string, params interface{}) MessageOut {

    m := MessageOut{}
    m.JSONRPC = "2.0"
    m.Method = &method
    m.Params = &params

    return m

}

type Test struct {
        A string `json:"a"`
        B string `json:"b"`
}

# let WriteJSON do all marshalling 
t := Test{"abc", "def"}

m := NewNotification("testMethod", t)

socket.WriteJSON(m)

# unmarshal manually received message when method is known
m := Message{}
socket.ReadJSON(m)

t := Test{}

json.Unmarshal(m.Params, &t)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    相关资源
    最近更新 更多