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
相关产品推荐
相关产品推荐

