Go语言json.Marshal多态机制

文章目录

什么是 Go语言json.Marshal多态机制

在Go语言中,json.Marshal提供了强大的多态机制,允许不同类型的结构体根据自己的需求定制JSON序列化行为。这种机制主要通过实现json.Marshaler接口来实现。

Go语言的json.Marshal多态机制提供了强大的序列化定制能力,主要应用场景包括:

  • 数据脱敏:隐藏或掩码敏感信息
  • 权限控制:根据用户角色显示不同数据
  • API版本兼容:同一数据结构支持多种输出格式
  • 性能优化:减少不必要的字段序列化
  • 日志安全:确保日志中不包含敏感信息
    通过实现MarshalJSON方法,我们可以在保持代码简洁的同时,实现复杂的业务需求。这种机制体现了Go语言接口设计的优雅性和实用性。

主要用于需要定制JSON输出的场景。json.Marshal多态机制的核心就是:当标准的JSON序列化无法满足需求时,提供自定义输出格式的能力。

每个自定义MarshalJSON都对应一个具体的业务需求

json.Marshaler接口

go 复制代码
type Marshaler interface {
    MarshalJSON() ([]byte, error)
}

任何实现了MarshalJSON() ([]byte, error)方法的类型,在调用json.Marshal时都会自动使用其自定义的序列化逻辑

demo场景1:用户信息脱敏

go 复制代码
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))
}

输出:

bash 复制代码
{
  "id": 12345,
  "username": "john_doe",
  "email": "j***e@company.com",
  "phone": "138****8000"
}
相关推荐
七七&5561 小时前
2024年08月13日 Go生态洞察:Go 1.23 发布与全面深度解读
开发语言·网络·golang
java坤坤1 小时前
GoLand 项目从 0 到 1:第八天 ——GORM 命名策略陷阱与 Go 项目启动慢问题攻坚
开发语言·后端·golang
元清加油1 小时前
【Golang】:函数和包
服务器·开发语言·网络·后端·网络协议·golang
No0d1es2 小时前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
大阳1234 小时前
线程(基本概念和相关命令)
开发语言·数据结构·经验分享·算法·线程·学习经验
恋喵大鲤鱼4 小时前
Golang 后台技术面试套题 1
面试·golang
weixin_307779135 小时前
VS Code配置MinGW64编译GNU 科学库 (GSL)
开发语言·c++·vscode·算法
学行库小秘6 小时前
ANN神经网络回归预测模型
人工智能·python·深度学习·神经网络·算法·机器学习·回归
Yn3126 小时前
在 Python 中使用 json 模块的完整指南
开发语言·python·json
没落之殇6 小时前
基于C语言实现的HRV分析方法 —— 与Kubios和MATLAB对比
算法