在使用 Go语言 开发Web服务或处理API数据时,我们经常需要将Go结构体转换为JSON格式(序列化),或将JSON数据解析回Go结构体(反序列化)。这一过程通常由标准库 encoding/json 包完成。然而,在实际项目中,你可能会遇到默认行为无法满足需求的情况——比如字段命名不一致、忽略空值、自定义时间格式等。这时,就需要用到 Go语言自定义JSON序列化 的能力。

默认情况下,encoding/json 包会将结构体中首字母大写的字段(即导出字段)按原名转为JSON键。但现实场景中,我们可能希望:
UserName → user_name)幸运的是,Go 提供了多种方式实现这些需求。
最简单的方式是通过 json 标签来自定义字段映射。例如:
package mainimport ( "encoding/json" "fmt")type User struct { ID int `json:"id"` UserName string `json:"user_name"` Password string `json:"-"` // 跳过该字段 Email string `json:"email,omitempty"` // 如果为空则忽略}func main() { u := User{ ID: 1, UserName: "alice", Password: "secret123", Email: "", // 空值 } data, _ := json.Marshal(u) fmt.Println(string(data)) // 输出: {"id":1,"user_name":"alice"}}在这个例子中:
json:"id" 将字段名改为 idjson:"-" 表示完全忽略该字段(常用于敏感信息)json:"email,omitempty" 表示如果 Email 为空字符串,则不在JSON中输出当结构体标签无法满足复杂逻辑时(例如需要将多个字段合并为一个JSON字段,或自定义时间格式),我们可以让类型实现 json.Marshaler 和 json.Unmarshaler 接口。
下面是一个自定义时间格式的例子:
package mainimport ( "encoding/json" "fmt" "time")// CustomTime 自定义时间类型type CustomTime struct { time.Time}// MarshalJSON 实现自定义序列化func (ct CustomTime) MarshalJSON() ([]byte, error) { if ct.Time.IsZero() { return []byte("null"), nil } // 使用 RFC3339 格式,也可自定义如 "2006-01-02" return []byte(fmt.Sprintf(`"%s"`, ct.Format("2006-01-02"))), nil}// UnmarshalJSON 实现自定义反序列化func (ct *CustomTime) UnmarshalJSON(data []byte) error { if string(data) == "null" { return nil } t, err := time.ParseInLocation(`"2006-01-02"`, string(data), time.Local) if err != nil { return err } ct.Time = t return nil}type Event struct { Name string `json:"name"` StartTime CustomTime `json:"start_time"`}func main() { e := Event{ Name: "会议", StartTime: CustomTime{time.Date(2024, 5, 20, 0, 0, 0, 0, time.Local)}, } data, _ := json.Marshal(e) fmt.Println(string(data)) // 输出: {"name":"会议","start_time":"2024-05-20"} var e2 Event json.Unmarshal(data, &e2) fmt.Printf("解析后时间: %v\n", e2.StartTime.Format("2006-01-02"))}通过实现这两个接口,你可以完全掌控序列化和反序列化的行为。这是处理 Go JSON Marshal 复杂场景的强大工具。
有时你可能希望对整个结构体进行控制,而不是单个字段。这时可以直接为结构体定义 MarshalJSON() 和 UnmarshalJSON() 方法。
type Person struct { FirstName string LastName string}// 将 FirstName 和 LastName 合并为 fullNamefunc (p Person) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]string{ "fullName": p.FirstName + " " + p.LastName, })}// 反序列化时拆分 fullNamefunc (p *Person) UnmarshalJSON(data []byte) error { var temp struct { FullName string `json:"fullName"` } if err := json.Unmarshal(data, &temp); err != nil { return err } parts := strings.SplitN(temp.FullName, " ", 2) if len(parts) == 2 { p.FirstName = parts[0] p.LastName = parts[1] } return nil}通过本文,你已经掌握了在 Go语言 中使用 encoding/json 包进行 自定义JSON序列化 的三种主要方法:
Marshaler/Unmarshaler 接口(适合字段级复杂逻辑)MarshalJSON/UnmarshalJSON(适合整体结构变换)无论你是初学者还是有经验的开发者,理解这些机制都能让你更灵活地处理 Go结构体序列化 问题,写出更健壮、可维护的代码。
希望这篇教程对你有所帮助!如果你正在构建API服务,别忘了合理使用这些技巧来提升数据交互的清晰度和安全性。
本文由主机测评网于2025-12-12发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025126469.html