You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将第三方库的CredentialResult结构体转为指定JSON格式?

问题:将第三方库的CredentialResult结构体转换为指定格式JSON

第三方库定义的Golang结构体如下:

type Credentials struct {
    TmpSecretID  string `json:"TmpSecretId,omitempty"`
    TmpSecretKey string `json:"TmpSecretKey,omitempty"`
    SessionToken string `json:"Token,omitempty"`
}

type CredentialError struct {
    Code      string `json:"Code,omitempty"`
    Message   string `json:"Message,omitempty"`
    RequestId string `json:"RequestId,omitempty"`
}

type CredentialResult struct {
    Credentials *Credentials     `json:"Credentials,omitempty"`
    ExpiredTime int              `json:"ExpiredTime,omitempty"`
    Expiration  string           `json:"Expiration,omitempty"`
    StartTime   int              `json:"StartTime,omitempty"`
    RequestId   string           `json:"RequestId,omitempty"`
    Error       *CredentialError `json:"Error,omitempty"`
}

需要转换为如下格式的JSON:

{
    "credentials":{
        "tmpSecretId":"",
        "tmpSecretKey":"",
        "sessionToken":""
    },
    "requestId":"",
    "expiration":"",
    "startTime":1,
    "expiredTime":1
}
最优实现方案

方法一:自定义映射结构体(推荐)

这种方式直观易懂,代码可维护性高,是最常用的最优方案。核心思路是定义一个与目标JSON结构完全匹配的本地结构体,手动将第三方结构体的字段值映射过去,再序列化。

package main

import (
    "encoding/json"
    "fmt"
)

// 第三方库结构体(实际使用时直接引用第三方库即可)
type Credentials struct {
    TmpSecretID  string `json:"TmpSecretId,omitempty"`
    TmpSecretKey string `json:"TmpSecretKey,omitempty"`
    SessionToken string `json:"Token,omitempty"`
}

type CredentialResult struct {
    Credentials *Credentials `json:"Credentials,omitempty"`
    ExpiredTime int          `json:"ExpiredTime,omitempty"`
    Expiration  string       `json:"Expiration,omitempty"`
    StartTime   int          `json:"StartTime,omitempty"`
    RequestId   string       `json:"RequestId,omitempty"`
}

// 定义与目标JSON匹配的本地结构体
type TargetCredentialResult struct {
    Credentials struct {
        TmpSecretID  string `json:"tmpSecretId"`
        TmpSecretKey string `json:"tmpSecretKey"`
        SessionToken string `json:"sessionToken"`
    } `json:"credentials"`
    RequestId   string `json:"requestId"`
    Expiration  string `json:"expiration"`
    StartTime   int    `json:"startTime"`
    ExpiredTime int    `json:"expiredTime"`
}

// 转换函数:将第三方结构体转为本地目标结构体
func ConvertToTargetFormat(src *CredentialResult) (*TargetCredentialResult, error) {
    if src == nil {
        return nil, fmt.Errorf("source CredentialResult cannot be nil")
    }

    target := &TargetCredentialResult{
        RequestId:   src.RequestId,
        Expiration:  src.Expiration,
        StartTime:   src.StartTime,
        ExpiredTime: src.ExpiredTime,
    }

    // 处理嵌套的Credentials字段
    if src.Credentials != nil {
        target.Credentials.TmpSecretID = src.Credentials.TmpSecretID
        target.Credentials.TmpSecretKey = src.Credentials.TmpSecretKey
        target.Credentials.SessionToken = src.Credentials.SessionToken
    }

    return target, nil
}

func main() {
    // 模拟从第三方库获取的CredentialResult实例
    srcResult := &CredentialResult{
        Credentials: &Credentials{
            TmpSecretID:  "test-id",
            TmpSecretKey: "test-key",
            SessionToken: "test-token",
        },
        RequestId:   "req-123",
        Expiration:  "2024-12-31T12:00:00Z",
        StartTime:   1735689600,
        ExpiredTime: 1735693200,
    }

    // 转换并序列化
    targetResult, err := ConvertToTargetFormat(srcResult)
    if err != nil {
        fmt.Printf("convert error: %v\n", err)
        return
    }

    jsonBytes, err := json.MarshalIndent(targetResult, "", "    ")
    if err != nil {
        fmt.Printf("marshal error: %v\n", err)
        return
    }

    fmt.Println(string(jsonBytes))
}

优点:

  • 代码逻辑清晰,可读性强,后续字段修改时易维护
  • 序列化性能高,无需额外的JSON处理逻辑
  • 可灵活处理字段默认值、空值等特殊情况

方法二:自定义MarshalJSON方法

如果不想额外定义结构体,可以给CredentialResult类型实现json.Marshaler接口,直接控制序列化后的JSON格式。

package main

import (
    "encoding/json"
    "fmt"
)

// 第三方库结构体(实际使用时直接引用第三方库即可)
type Credentials struct {
    TmpSecretID  string `json:"TmpSecretId,omitempty"`
    TmpSecretKey string `json:"TmpSecretKey,omitempty"`
    SessionToken string `json:"Token,omitempty"`
}

type CredentialResult struct {
    Credentials *Credentials `json:"Credentials,omitempty"`
    ExpiredTime int          `json:"ExpiredTime,omitempty"`
    Expiration  string       `json:"Expiration,omitempty"`
    StartTime   int          `json:"StartTime,omitempty"`
    RequestId   string       `json:"RequestId,omitempty"`
}

// 给CredentialResult实现自定义MarshalJSON方法
func (cr *CredentialResult) MarshalJSON() ([]byte, error) {
    if cr == nil {
        return []byte("null"), nil
    }

    // 定义临时结构体匹配目标JSON格式
    type tmpCredentials struct {
        TmpSecretID  string `json:"tmpSecretId"`
        TmpSecretKey string `json:"tmpSecretKey"`
        SessionToken string `json:"sessionToken"`
    }

    tmpStruct := struct {
        Credentials *tmpCredentials `json:"credentials"`
        RequestId   string          `json:"requestId"`
        Expiration  string          `json:"expiration"`
        StartTime   int             `json:"startTime"`
        ExpiredTime int             `json:"expiredTime"`
    }{
        RequestId:   cr.RequestId,
        Expiration:  cr.Expiration,
        StartTime:   cr.StartTime,
        ExpiredTime: cr.ExpiredTime,
    }

    if cr.Credentials != nil {
        tmpStruct.Credentials = &tmpCredentials{
            TmpSecretID:  cr.Credentials.TmpSecretID,
            TmpSecretKey: cr.Credentials.TmpSecretKey,
            SessionToken: cr.Credentials.SessionToken,
        }
    }

    return json.Marshal(tmpStruct)
}

func main() {
    // 模拟第三方库返回的实例
    srcResult := &CredentialResult{
        Credentials: &Credentials{
            TmpSecretID:  "test-id",
            TmpSecretKey: "test-key",
            SessionToken: "test-token",
        },
        RequestId:   "req-123",
        Expiration:  "2024-12-31T12:00:00Z",
        StartTime:   1735689600,
        ExpiredTime: 1735693200,
    }

    // 直接序列化原结构体
    jsonBytes, err := json.MarshalIndent(srcResult, "", "    ")
    if err != nil {
        fmt.Printf("marshal error: %v\n", err)
        return
    }

    fmt.Println(string(jsonBytes))
}

适用场景:

  • 临时转换场景,不想额外定义结构体
  • 第三方结构体字段固定,后续不会频繁变动

方案选择建议

如果是长期使用的业务场景,优先选择方法一,因为代码的可维护性和可读性更好;如果是临时的一次性转换,可以使用方法二简化代码。

内容的提问来源于stack exchange,提问作者OneQ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 17:41:04