什么是 Go语言json.Marshal多态机制
在Go语言中,json.Marshal提供了强大的多态机制,允许不同类型的结构体根据自己的需求定制JSON序列化行为。这种机制主要通过实现json.Marshaler接口来实现。
Go语言的json.Marshal多态机制提供了强大的序列化定制能力,主要应用场景包括:
- 数据脱敏:隐藏或掩码敏感信息
- 权限控制:根据用户角色显示不同数据
- API版本兼容:同一数据结构支持多种输出格式
- 性能优化:减少不必要的字段序列化
- 日志安全:确保日志中不包含敏感信息
通过实现MarshalJSON方法,我们可以在保持代码简洁的同时,实现复杂的业务需求。这种机制体现了Go语言接口设计的优雅性和实用性。
主要用于需要定制JSON输出的场景。json.Marshal多态机制的核心就是:当标准的JSON序列化无法满足需求时,提供自定义输出格式的能力。
每个自定义MarshalJSON都对应一个具体的业务需求
json.Marshaler接口
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
任何实现了MarshalJSON() ([]byte, error)方法的类型,在调用json.Marshal时都会自动使用其自定义的序列化逻辑。
demo场景1:用户信息脱敏
package main
import (
"encoding/json"
"fmt"
"strings"
)
// 用户基础信息
type User struct {
ID int64 `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
Phone string `json:"phone"`
Password string `json:"-"` // 完全隐藏
}
// 实现自定义JSON序列化
func (u User) MarshalJSON() ([]byte, error) {
// 创建一个匿名结构体用于序列化
type UserAlias User // 避免无限递归
return json.Marshal(&struct {
UserAlias
Email string `json:"email"`
Phone string `json:"phone"`
}{
UserAlias: UserAlias(u),
Email: maskEmail(u.Email),
Phone: maskPhone(u.Phone),
})
}
// 邮箱脱敏函数
func maskEmail(email string) string {
if email == "" {
return ""
}
parts := strings.Split(email, "@")
if len(parts) != 2 {
return email
}
username := parts[0]
domain := parts[1]
if len(username) <= 2 {
return email
}
masked := string(username[0]) + "***" + string(username[len(username)-1])
return masked + "@" + domain
}
// 手机号脱敏函数
func maskPhone(phone string) string {
if len(phone) < 7 {
return phone
}
return phone[:3] + "****" + phone[len(phone)-4:]
}
func main() {
user := User{
ID: 12345,
Username: "john_doe",
Email: "john.doe@company.com",
Phone: "13800138000",
Password: "secret123", // 这个字段不会出现在JSON中
}
data, err := json.Marshal(user)
if err != nil {
panic(err)
}
fmt.Println("脱敏后的用户信息:")
fmt.Println(string(data))
}
输出:
{
"id": 12345,
"username": "john_doe",
"email": "j***e@company.com",
"phone": "138****8000"
}