簡體   English   中英

在Golang中解碼任意JSON

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM