Golang JSON 序列化时动态忽略字段
2024-12-18 21:18:31+08:00
Golang JSON 序列化时动态忽略字段
在使用 JSON 时经常遇到需要忽略字段的情况,例如返回用户信息时不能返回密码,通常将注解 TAG 设为 json:"-"
即可:
type User struct {
Account string `json:"account"`
Password string `json:"-"`
Nickname string `json:"nickname"`
}
但这样的静态配置会使字段在任何情况下都被忽略,有时希望可以根据需求动态的决定是否忽略某些字段。
可以通过反射将读取对象的字段名和字段值,过滤忽略的字段后存入一个 map[string]any
中,然后进行序列化:
package utils
import (
"encoding/json"
"reflect"
)
func JsonMarshalWithFilter(data any, ignore []string) ([]byte, error) {
filter := make(map[string]bool)
for i := range ignore {
name := ignore[i]
filter[name] = true
}
m := make(map[string]any)
metaType := reflect.TypeOf(data)
metaValue := reflect.ValueOf(data)
n := metaType.NumField()
for i := 0; i < n; i++ {
field := metaType.Field(i)
name := field.Tag.Get("json")
if filter[name] {
continue
}
value := metaValue.Field(i).Interface()
m[name] = value
}
return json.Marshal(m)
}
调用:
package main
import "utils"
type User struct {
Account string `json:"account"`
Password string `json:"password"`
Nickname string `json:"nickname"`
}
func main() {
user := schema.User{
Account: "hubenchang0515",
Password: "xxxxxxxxx",
Nickname: "planc0515",
}
data, _ := utils.JsonMarshalWithFilter(user, []string{"password"})
println(string(data))
}
$ go run .
{"account":"hubenchang0515","nickname":"planc0515"}