json - 隐藏 JSON 中的属性

标签 json go

我有一个包含 2 个播放器的结构表,但在发送 JSON 时我需要忽略结构 Player 中的一些属性。

我可以使用 json:"-",但是该属性将始终被忽略,并且只有在发送 Table 结构时我才需要忽略它。当我在代码的其他部分发送 Player 时,我需要这些属性。

我有:

type Player struct {
    Id            Int64   `json:"id"`
    Username      string  `json:"username,omitempty"`
    Password      string          `json:"-,omitempty"`
    Email         string          `json:"email,omitempty"`
    Birthdate     time.Time       `json:"birthdate,omitempty"`
    Avatar        string  `json:avatar,omitempty"`
}

type Table struct {
    Id           int       `json:"id"`
    PlayerTop    Player      `json:"playerTop"`
    PlayerBottom Player      `json:"playerBottom"`
}

我需要:

{
    "Table": {
        "id": 1,
        "playerBottom": {
            "id": 1,
            "username": "peter",
            "avatar": "avatar.png"
        },
        "playerTop": {
            "id": 1,
            "username": "peter",
            "avatar": "avatar.png"
        }

    }
}

玩家来自数据库,所以属性不为空。

a) 我可以这样做:

myTable = new(Table)

myTable.PlayerBottom.Email = ""
myTable.PlayerBottom.Birthdate = ""
myTable.PlayerTop.Email = ""
myTable.PlayerTop.Birthdate = ""

所以这些属性将在 JSON 中被忽略,感谢 json:"omitempty",但这是个坏主意。

b) 我可以使用别名结构之类的东西,但是 Table 期望 PlayerBottomPlayer 类型而不是 PlayerAlias,但我不知道如何实现它:

type PlayerAlias struct {
    Id            Int64   `json:"id"`
    Username      string  `json:"username,omitempty"`
    Avatar        string  `json:avatar,omitempty"`
}

c) 在发送之前,我尝试动态添加 json:"-" 到我不想要的 JSON 属性,但结果一团糟。

最佳答案

您可以为 Table 类型创建自定义 Marshaler。这是您必须实现的接口(interface):

https://golang.org/pkg/encoding/json/#Marshaler

type Marshaler interface {
        MarshalJSON() ([]byte, error)
}

然后您将从 Player 中删除 - 标记(因为当您在别处编码它时您需要保留字段)并且仅在自定义 中忽略它Table 的 >MarshalJSON 方法。


这是一个简单的(不相关的)示例,它为一种类型实现自定义编码(marshal)处理,以十六进制编码其中一个字段:

type Account struct {
    Id   int32
    Name string
}

func (a Account) MarshalJSON() ([]byte, error) {
    m := map[string]string{
        "id":   fmt.Sprintf("0x%08x", a.Id),
        "name": a.Name,
    }
    return json.Marshal(m)
}

func main() {
    joe := Account{Id: 123, Name: "Joe"}
    fmt.Println(joe)

    s, _ := json.Marshal(joe)
    fmt.Println(string(s))
}

正如您在此处看到的,通过构建一个只包含您需要的字段的 map 并将其传递给 json.Marshal,可以很容易地完成这种编码(marshal)处理。对于您的 TablePlayer,这只会产生几行简单的代码。恕我直言,这样做比修改类型并使用嵌入/别名使它们复杂化更好,只是为了 JSON 编码。

关于json - 隐藏 JSON 中的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54751615/

相关文章:

java - JodaTime 日期的序列化和反序列化为 json

php - 在 PHP 中设置 TCP 监听器

go - 不支持扫描,将 driver.Value 类型 []uint8 存储为 *[]string 类型

go - ZeroMQ中的PUB/SUB模式不起作用

ios - 无法使用 Wordpress 中的高级自定义字段值

javascript - 我应该担心这个 422(不可处理实体)错误吗? ( rails 与设计)

ios - 在 Swift 的 MailJet 电子邮件中附加 PDF

go - 如何使用urfave/cli实现OptionFlag

bash - 使用 Go 运行带参数的 bash 文件

multithreading - Golang线程不是每次都执行