
本文详解如何在go中正确解析包含深层转义json字符串的响应,重点解决结构体字段名拼写错误、json键名不匹配及转义字符导致的解析失败问题。
本文详解如何在go中正确解析包含深层转义json字符串的响应,重点解决结构体字段名拼写错误、json键名不匹配及转义字符导致的解析失败问题。
在Go中解析JSON时,若目标字段值本身是已序列化的JSON字符串(即双重编码),且原始JSON中存在大量转义字符(如"、\、<\/src>等),常见错误往往并非语法或编码问题,而是结构体字段标签与JSON键名不一致或字段名拼写错误。
例如,原始JSON中字段名为 "description",但结构体中误写为 Destription(少一个 c),导致encoding/json包无法匹配并赋值——此时该字段将保持零值(空字符串),看似“解析成功”实则静默丢失数据。
✅ 正确做法如下:
- 严格对齐字段名:Go的json包默认按字段名(首字母大写)匹配JSON键,需确保结构体字段名与JSON键完全一致(忽略大小写?否!严格区分),并推荐显式声明json标签增强可读性与健壮性:
type DataSlice struct {
ID int `json:"id"`
Description string `json:"description"`
}-
无需特殊处理转义字符串:只要JSON格式合法(外层JSON有效),description字段值即使包含XML、双引号、反斜杠等,也会被json.Unmarshal原样解码为Go字符串——Go的encoding/json天然支持标准JSON转义规则(如" → ", → )。你只需将其作为普通字符串接收并存入数据库即可。
立即学习“go语言免费学习笔记(深入)”;
完整可运行示例(含HTTP请求与错误处理):
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
)
type DataSlice struct {
ID int `json:"id"`
Description string `json:"description"`
}
func main() {
// 模拟服务端响应(实际使用时替换为真实URL)
mockResp := `{
"id": 1,
"description": "{"uDes":"","reDes":[{"des":"aaa,,request=<?xml version=\"1.0\" encoding=\"GBK\"?><Req ver=\"3.0\"><HR version=\"3.0\" cd=\"0\"><src><\/src><license><\/license><clientid>com.sample.xo<\/clientid><ii>8603<\/ii><im>46002910<\/im><uuid>da032b2<\/uuid><reqid>-21851<\/reqid><smc>44:91<\/smc><sdv>2.0.201501131131.a.r<\/sdv><corv>V1.1.0r<\/corv><\/HDR><DRR nettype=\"LTE\" inftype=\"1\"><mc>460<\/cc><mnc>00<\/mnc><lac>34809<\/lac><cellid>8842241<\/cellid><signal>-69<\/signal><\/DRR><\/Cell_Req>&retype=3×tamp=1469550331136"}]}"
}`
resp := &http.Response{
Body: io.NopCloser(strings.NewReader(mockResp)),
}
defer resp.Body.Close()
var data DataSlice
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
panic(fmt.Sprintf("JSON decode error: %v", err))
}
fmt.Printf("ID: %d
", data.ID)
fmt.Printf("Description length: %d
", len(data.Description))
fmt.Printf("First 100 chars: %s
", strings.TrimSuffix(data.Description[:min(100, len(data.Description))], "
"))
}
func min(a, b int) int {
if a < b {
return a
}
return b
}⚠️ 注意事项:
- 永远启用json标签:避免依赖默认命名规则,提升代码可维护性与兼容性;
- 检查HTTP状态码:resp.StatusCode应为200,否则可能返回非JSON错误页;
- defer resp.Body.Close()必须在Decode前调用,防止资源泄漏;
- 若description后续还需二次解析为JSON对象,可再调用json.Unmarshal([]byte(data.Description), &target),但本文场景仅需存储原始字符串,无需额外解析。
总结:Go解析此类“JSON内嵌JSON字符串”的核心在于字段映射准确 + 接受字符串原样值。修正拼写错误、添加结构体标签,并信任标准库对转义字符的正确处理能力,即可稳定可靠地完成数据提取与持久化。


















