【问题标题】:How to ignore JSON fields when marshalling not unmarshalling编组不解组时如何忽略 JSON 字段
【发布时间】:2024-04-15 23:00:02
【问题描述】:

假设我在用户结构中有一个密码字段。

type User struct{
   UserName string `json:"username"`
   Password string `json:"-"`
}

我的客户通过同时发布用户名和密码来注册他们的用户。因此,如果我将 JSON 解码为上述结构,它会忽略密码。这是预期的。但我想知道只有编组时有什么方法可以忽略字段。我检查了 go 官方文档页面,但找不到任何东西。

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

我可以在结构中添加一个额外的字段,但我首先需要知道是否可以使用 JSON 库来做到这一点。

【问题讨论】:

  • 创建两个结构,两个映射分别用于编码和解码
  • 但首先我需要知道没有办法使用 json 表示法来做到这一点。

标签: json go


【解决方案1】:

一种常见的方法是使用临时类型或变量,结构相同,但json标签不同,甚至结构不同:

type User struct {
    UserName string `json:"username"`
    Password string `json:"password"`
}

func (usr User) MarshalJSON() ([]byte, error) {
    var tmp struct {
        UserName string `json:"username"`
    }
    tmp.UserName = usr.UserName
    return json.Marshal(&tmp)
}

【讨论】:

    【解决方案2】:

    与 Go 中的任何自定义编组/取消编组要求一样,最好的办法是查看在自定义类型上实现 json.Marshaler/json.Unmarshaler 接口。

    在这种情况下,您可以对密码字段进行操作:

    // Use an explicit password type.
    type password string
    
    type User struct{
        UserName string   `json:"username"`
        Password password `json:"password"`
    }
    
    // Marshaler ignores the field value completely.
    func (password) MarshalJSON() ([]byte, error) {
        return []byte(`""`), nil
    }
    

    请注意,通过不实现 json.Unmarshaler,类型 password 保留其基础类型 (string) 的默认行为,这允许使用 Password 值解组结构。

    工作示例:https://play.golang.org/p/HZQoCKm0vN

    【讨论】:

    • 我还建议添加String() 以确保覆盖结构的所有常规序列化(例如,在调试日志中打印时) ``` func (password) String() string {返回“”}```
    【解决方案3】:

    我更喜欢字体组合。例如:

    type User struct {
        UserName string `json:"username"`
    }
    
    type UserWithPassword struct {
        *User
        Password string `json:"password"`
    }
    

    在接收数据时使用 UserWithPassword(例如用户创建/修改),在返回数据时使用 User(身份验证)。

    【讨论】:

      【解决方案4】:

      如果您想知道在BOTH编组解组时如何忽略 JSON 字段:

          Ulimit struct {
              Soft uint64 `json:"-"`    // this attribute will be ignored
              Hard uint64 `json:"hard"`
          } `json:"ulimit"`
      

      PS:我知道这并不能回答这个确切的问题,但谷歌搜索查询将开发人员带到这里“如何忽略 Go 中的 JSON 字段”,所以我希望这会有所帮助。几分钟前我来到这里寻找这个答案。

      【讨论】:

        最近更新 更多