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

如何在Go中无需额外转义/编组将含空格制表符的原始JSON传入结构体

解决Go结构体编组时JSON字符串额外转义问题

核心方案:为BrandTemplate实现自定义MarshalJSON方法

如果你不想修改BrandTemplate的字段类型(保持Template为string),可以通过实现json.Marshaler接口,手动控制结构体的JSON编组逻辑,让Template字段直接输出原始JSON内容而非转义后的字符串。

代码实现

import (
    "encoding/json"
    "errors"
)

type BrandTemplate struct {
    Type     string `json:"type"`     // Template type (e.g., email_forgot_password)
    Locale   string `json:"locale"`   // Locale (e.g., "es" for Spanish, "en" for English)
    Template string `json:"template"` // Template content (Email/SMS content)
}

// MarshalJSON 自定义编组逻辑,避免Template字段被转义
func (bt BrandTemplate) MarshalJSON() ([]byte, error) {
    // 先验证Template是否是合法JSON,避免输出无效JSON
    if !json.Valid([]byte(bt.Template)) {
        return nil, errors.New("template is not valid JSON")
    }

    // 构造临时结构体,将Template转为json.RawMessage
    type TempBrandTemplate struct {
        Type     string          `json:"type"`
        Locale   string          `json:"locale"`
        Template json.RawMessage `json:"template"`
    }

    temp := TempBrandTemplate{
        Type:     bt.Type,
        Locale:   bt.Locale,
        Template: json.RawMessage(bt.Template),
    }

    // 编组临时结构体,此时Template会以原始JSON形式输出
    return json.Marshal(temp)
}

使用示例

// 定义原始JSON模板字符串
template := `{
    "subject": "Email MFA App Verification Code",
    "html": "<html><head></head><body><p>Here is the code: {{otp_code}}</p></body></html>",
    "plain": "Here is the code: {{otp_code}}"
}`

brandTemplate := BrandTemplate{
    Type:     "email_code_app_verification",
    Locale:   "en",
    Template: template,
}

// 编组结构体,此时Template字段不会被额外转义
result, err := json.MarshalIndent(brandTemplate, "", "  ")
if err != nil {
    panic(err)
}

println(string(result))

输出效果

编组后的JSON会将template字段作为原始JSON对象输出,而非转义字符串:

{
  "type": "email_code_app_verification",
  "locale": "en",
  "template": {
    "subject": "Email MFA App Verification Code",
    "html": "<html><head></head><body><p>Here is the code: {{otp_code}}</p></body></html>",
    "plain": "Here is the code: {{otp_code}}"
  }
}

补充:反序列化的处理(可选)

如果需要将JSON反序列化为BrandTemplate结构体,同时让Template字段保留原始JSON字符串,还需要实现json.Unmarshaler接口:

// UnmarshalJSON 自定义反序列化逻辑
func (bt *BrandTemplate) UnmarshalJSON(data []byte) error {
    type TempBrandTemplate struct {
        Type     string          `json:"type"`
        Locale   string          `json:"locale"`
        Template json.RawMessage `json:"template"`
    }

    var temp TempBrandTemplate
    if err := json.Unmarshal(data, &temp); err != nil {
        return err
    }

    bt.Type = temp.Type
    bt.Locale = temp.Locale
    bt.Template = string(temp.Template)
    return nil
}

注意事项

  • 必须确保Template字段的字符串是合法的JSON,否则自定义编组会返回错误。如果需要支持非JSON格式的模板内容,建议保留默认的字符串转义逻辑,或者在验证失败时fallback到默认处理。
  • 自定义编组/反序列化方法会覆盖默认的JSON处理逻辑,后续如果结构体字段有修改,需要同步更新这些方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:53:12