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

Go解析含转义斜杠的JSON自定义时间反序列化失败如何处理

问题根因
  • 初始测试代码触发语法错误的核心原因是传入json.Unmarshal的内容不是合法的完整JSON值:JSON规范要求字符串值必须用双引号包裹,直接传入无引号的6\/30\/2022 21:51:49本身就不符合JSON语法,和\/转义无关。
  • strconv.Unquote适配的是Go语言自身的字符串字面量转义规则,和JSON转义规则并不完全一致:Go语法中\/不属于合法转义序列,因此调用该方法处理JSON字符串会报未知转义错误,属于工具选型错误。
  • 自定义UnmarshalJSON方法中直接截断双引号取原始字节的逻辑,跳过了标准库JSON字符串解析的转义处理步骤:传入方法的[]byte参数是未经解析的原始JSON片段,其中的\/还是转义序列形态,没有被转换为真实的/字符,直接传给time.Parse自然会匹配失败。
  • Go标准库encoding/json完全符合RFC 8259规范,原生支持\/转义序列的解析,默认反序列化字符串时会自动将\/转换为普通斜杠,不存在不支持合法JSON转义的问题。
正确处理方案

不需要手动做字节替换,也不需要自行实现转义逻辑,在自定义反序列化方法中先将原始JSON片段反序列化为普通Go字符串,让标准库完成所有合法转义的处理后,再做时间格式解析即可,该方案兼容所有合法JSON转义场景,不会出现误替换问题。

修正后的自定义时间类型反序列化代码如下:

type Request struct {
    CreatedAt Time `json:"created_at"`
}

type Time time.Time

func (d *Time) UnmarshalJSON(b []byte) error {
    // 先将原始JSON字符串片段反序列化为普通string,自动完成所有JSON转义处理
    var timeStr string
    if err := json.Unmarshal(b, &timeStr); err != nil {
        return err
    }
    // 此时timeStr中已无转义字符,直接按指定格式解析时间
    parsed, err := time.Parse("1/2/2006 15:04:05", timeStr)
    if err != nil {
        return err
    }
    *d = Time(parsed)
    return nil
}

// 按需实现String、MarshalJSON等配套方法即可

基础场景下的JSON字符串反序列化验证代码:

func main() {
    var s string
    // 传入的是带双引号的完整JSON字符串值
    err := json.Unmarshal([]byte(`"6\/30\/2022 21:51:49"`), &s)
    fmt.Println(s, err)
    // 输出结果: 6/30/2022 21:51:49 <nil>
}

注意:不要使用strings.ReplaceAll全局替换\/为/,该逻辑无法处理嵌套转义场景(比如字符串中真实存在的\\/序列会被错误替换),存在兼容性隐患。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:54:15