dongtanliefang8765
2017-11-13 02:16
浏览 63

Golang在编组而不是编组时会忽略Json字段

Assume I have a password field in a User struct.

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

My clients register their users by posting username and password together. So if I decode JSON to above struct, it ignores password. It's expected. But I wondered is there any way to ignore fields when only marshalling. I checked go official documentation page but couldn't find anything.

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

I can add an extra field into the struct but I need to know first is it possible to do that with JSON lib.

图片转代码服务由CSDN问答提供 功能建议

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

 类型用户结构{
 UserName字符串`json:“ username”`
密码字符串`json:“-”`
} 
   
 
 

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

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

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

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • dsa80833 2017-11-13 08:21
    已采纳

    One common approach is to use a temporary type or variable, with same structure, but different json tags or even different structure:

    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)
    }
    
    打赏 评论
  • douyakan8924 2017-11-13 03:02

    As with any custom marshaling/unmarshaling requirements in Go, your best bet is to look at implementing json.Marshaler/json.Unmarshaler interface on a custom type.

    In this case, you can do it for the password field:

    // 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
    }
    

    Note that by not implementing json.Unmarshaler, type password retains the default behavior of its underlying type (string), which allows the struct to be unmarshalled with the Password value.

    Working example: https://play.golang.org/p/HZQoCKm0vN

    打赏 评论
  • dongqian6484 2018-12-28 15:36

    I prefer type composition. For example:

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

    use UserWithPassword when receiving data (eg. user creation / modification) and User when returning it (authentication).

    打赏 评论

相关推荐 更多相似问题