天天看點

golang結構體嵌套json序列化丢失

package main

import (
	"encoding/json"
	"fmt"
)

type Tmsg struct {
	ID      int    `json:"id"`
	Message string `json:"message"`
}

func (me Tmsg) MarshalJSON() ([]byte, error) {
	type Alias Tmsg
	return json.Marshal(&struct {
		Message string `json:"message"`
		Alias
	}{
		Message: "1",
		Alias:   (Alias)(me),
	})
}

type tuser struct {
	Tid      int    `json:"id"`
	Realname string `json:"realname"`
}

type responseDataf struct {
	Tmsg
	Tuser *tuser `json:"user"`
}

func main() {

	user := tuser{
		Tid:      1,
		Realname: "aaaa",
	}

	msg := Tmsg{
		ID:      2,
		Message: "sssss",
	}
	data := responseDataf{
		msg,
		&user,
	}
	message, _ := json.Marshal(data)

	fmt.Println(string(message))
}

// output: {"message":"1","id":2}
           

上面代碼輸出不是預期的

{"id":2,"message":"sssss","user":{"id":1,"realname":"aaaa"}}

因為golang結構體組合的原因,在序列化時發現

Tmsg

有實作

MarshalJSON

,是以直接使用了我們自己實作的

MarshaJSON

。當然

Unmarshal

也存在這個問題

如果想要自定義json序列化,但是又想完整的輸入内容,可以想下面這樣更改,給

Tmsg

取個名字。不過輸出和預期還是有點出入,但是影響不大。

package main

import (
	"encoding/json"
	"fmt"
)

type Tmsg struct {
	ID      int    `json:"id"`
	Message string `json:"message"`
}


type Tuser struct {
	ID      int    `json:"id"`
	Realname string `json:"realname"`
}

type responseDataf struct {
	Tg *Tmsg `json:"Tmsg"`
	Ter *Tuser `json:"Tuser"`
}

func (me Tmsg) MarshalJSON() ([]byte, error) {
	type Alias Tmsg
	return json.Marshal(&struct {
		Message string `json:"message"`
		Alias
	}{
		Message: "1",
		Alias:   (Alias)(me),
	})
}

func main() {

	user := Tuser{
		ID:1,
		Realname: "aaaa",
	}

	msg := Tmsg{
		ID:2,
		Message: "sssss",
	}
	data := responseDataf{
		Tg:&msg,
		Ter:&user,
	}
	message, _ := json.Marshal(data)
	fmt.Println(string(message))
}

// output: {"Tmsg":{"message":"1","id":2},"Tuser":{"id":1,"realname":"aaaa"}}
           

個人見解,如果有誤還望斧正。

測試相關代碼

https://github.com/whoisix/godemo/tree/master/json_struct

----更新----

發現github有一個issue https://github.com/golang/go/issues/39470