如何在Go中为结构体添加标签,以便从JSON中读取值但不写入值?

huangapple go评论86阅读模式
英文:

How to tag a struct in go such that it reads values from JSON but does not write them?

问题

我有以下的结构体,我想从JSON中读取并写入JSON。我想读取PasswordHash属性(反序列化),但在写入对象时跳过它(序列化)。

是否可以给对象打上标签,使其在反序列化时被读取,但在序列化时被忽略?json:"-"似乎会在两个操作中跳过该字段。

type User struct {
    // 必须是唯一的
    UserName string

    // 用户可以访问的项目集合
    Projects []string

    // 用户密码的哈希值
    // 使用标签使其在响应中不被序列化
    PasswordHash string `json:"-"`
    
    // 用户是否是管理员
    IsAdmin bool
}

我的反序列化代码如下:

var user User
content := // 一些内容
err := json.Unmarshal(content, &user)

序列化代码如下:

userBytes, _ := json.Marshal(user)
var respBuffer bytes.Buffer
json.Indent(&respBuffer, userBytes, "", "    ")
respBuffer.WriteTo(request.ResponseWriter)
英文:

I have the following struct that I want to read from JSON and Write to JSON. I want to read the PasswordHash property (deserialize it) but skip when writing the object (serialize it).

Is it possible to tag the object such that it that it is read when deserializing but ignored when serializing? the json:"-" seems to skip the field in both operations.

type User struct {

	// Must be unique
	UserName string

	// The set of projects to which this user has access
	Projects []string

	// A hash of the password for this user
	// Tagged to make it not serialize in responses
	PasswordHash string `json:"-"`

	// Is the user an admin
	IsAdmin bool
}

My deserialization code is as follows:

var user User
content = //Some Content
err := json.Unmarshal(content, &user)

and the serialization code is:

var userBytes, _ = json.Marshal(user)
var respBuffer bytes.Buffer
json.Indent(&respBuffer, userBytes, "", "	")
respBuffer.WriteTo(request.ResponseWriter)

答案1

得分: 5

我认为你不能使用json标签来实现这个,但是看起来输入用户和输出用户实际上是不同的语义对象。最好在代码中将它们分开。这样可以很容易地实现你想要的效果:

type UserInfo struct {
    // 必须是唯一的
    UserName string

    // 用户可以访问的项目集合
    Projects []string

    // 用户是否是管理员
    IsAdmin bool
}

type User struct {
    UserInfo

    // 用户的密码哈希值
    PasswordHash string
}

你的反序列化代码保持不变序列化代码只需要改变一行

```go
var userBytes, _ = json.Marshal(user.UserInfo)

play.golang.com

英文:

I think you can't do that with json tags, but looks like the input user and the output user are actually different semantic objects. It's better to separate them in code too. This way it's easy to achieve what you want:

type UserInfo struct {
	// Must be unique
	UserName string

	// The set of projects to which this user has access
	Projects []string

	// Is the user an admin
	IsAdmin bool
} 

type User struct {
	UserInfo

	// A hash of the password for this user
	PasswordHash string
}

Your deserialization code stay the same. Serialization code is changed in one line:

var userBytes, _ = json.Marshal(user.UserInfo)

play.golang.com

答案2

得分: 1

你不能使用标签来实现这个。你必须实现json.Marshaler来排除你想要排除的字段。

为结构体编写MarshalJSON可能有点棘手,因为你不想重写整个编组过程。我建议你创建一个type Password string,并为其编写一个编组器,以返回一个空的JSON表示。

英文:

You can’t do that with tags. You have to implement json.Marshaler to exclude the fields you want to exclude.

It would be a little tricky to write a MarshalJSON for the struct, because you don’t want to rewrite the whole marshaling. I recommend you have a type Password string, and write marshaler for that to return something empty as its JSON representation.

huangapple
  • 本文由 发表于 2013年9月12日 12:08:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/18755216.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定