[英]Decode arbitrary JSON in Golang
我有一個關於在Go中解碼任意JSON對象/消息的問題。比如說你有三個截然不同的JSON對象(也就是消息)你可以在http連接上接收,為了說明我們可以調用它們:
{ home : { some unique set of arrays, objects, fields, and arrays objects } }
和
{ bike : { some unique set of arrays, objects, fields, and arrays objects } }
和
{ soda : { some unique set of arrays, objects, fields, and arrays objects } }
我在想的是你可以解碼這些,從http連接到接口映射,例如:
func httpServerHandler(w http.ResponseWriter, r *http.Request) {
message := make(map[string]interface{})
decoder := json.NewDecoder(r.Body)
_ = decoder.Decode(&message)
然后執行if,else if塊查找有效的JSON消息
if _, ok := message["home"]; ok {
// Decode interface{} to appropriate struct
} else if _, ok := message["bike"]; ok {
// Decode interface{} to appropriate struct
} else {
// Decode interface{} to appropriate struct
}
現在在if塊我可以使它工作,如果我重新解碼整個包,但我認為這是一種浪費,因為我已經部分解碼它,只需要解碼地圖的值,這是一個接口{},但我似乎無法正常工作。
重新編碼整個東西,但如果我執行類似以下的操作,例如homeType是一個結構:
var homeObject homeType
var bikeObject bikeType
var sodaObject sodaType
然后在if塊中執行:
if _, ok := message["home"]; ok {
err = json.Unmarshal(r.Body, &homeObject)
if err != nil {
fmt.Println("Bad Response, unable to decode JSON message contents")
os.Exit(1)
}
因此,如果不再重新解碼/解組整個事物,您如何使用地圖中的界面{}?
如果您有類似map [string] interface {}的內容,那么您可以使用類型斷言來訪問這些值,例如
home, valid := msg["home"].(string)
if !valid {
return
}
這適用於簡單的值。 對於更復雜的嵌套結構,您可能會發現使用json.RawMessage
進行延遲解碼或實現自定義json.Unmarshaler
更容易。 有關詳細討論,請參閱此內容。
另一個想法可能是定義一個自定義Message
類型,其中包含指向Home,Bike和Soda結構的指針。 如
type Home struct {
HomeStuff int
MoreHomeStuff string
}
type Bike struct {
BikeStuff int
}
type Message struct {
Bike *Bike `json:"Bike,omitempty"`
Home *Home `json:"Home,omitempty"`
}
如果你將這些設置為省略nil那么解組應該只填充相關的那個。 你可以在這里玩。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.