Go语言如何读取JSON数组响应中的refresh_token字段值
问题原因
- 你调用
ioutil.ReadAll得到的respBody是[]byte(字节切片)类型,本质是二进制的JSON字符串,没有键值访问的能力,直接用字符串键索引会直接编译失败。 - 接口返回的JSON结构是数组包裹对象的格式,就算完成JSON解析,也需要先取数组第0位元素,才能访问到
refresh_token字段。 - 额外问题:你忽略了读取响应体、JSON解析可能的错误,且没有关闭
resp.Body会造成资源泄漏,在HTTP handler中调用os.Exit(1)会直接终止整个服务进程,不符合HTTP服务的错误处理逻辑。
修复后的代码
首先定义匹配JSON结构的结构体,再做JSON解析,示例代码如下:
import ( "encoding/json" "fmt" "io/ioutil" "net/http" "os" ) // 定义和返回JSON结构匹配的映射结构体 type TokenItem struct { RefreshToken string `json:"refresh_token"` } func Refresh(w http.ResponseWriter, r *http.Request) { client := &http.Client{} fetchUrl := "https://greatapiurl.com" req, err := http.NewRequest("GET", fetchUrl, nil) if err != nil { fmt.Println("创建请求失败:", err) http.Error(w, "内部服务错误", http.StatusInternalServerError) return } req.Header.Add("apikey", os.Getenv("ENV")) req.Header.Add("Authorization", "Bearer "+os.Getenv("ENV")) resp, err := client.Do(req) if err != nil { fmt.Println("发送请求失败:", err) http.Error(w, "内部服务错误", http.StatusInternalServerError) return } // 延迟关闭响应体避免资源泄漏 defer resp.Body.Close() respBody, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("读取响应失败:", err) http.Error(w, "内部服务错误", http.StatusInternalServerError) return } // 解析JSON:外层是数组,所以用切片类型接收 var tokenList []TokenItem err = json.Unmarshal(respBody, &tokenList) if err != nil { fmt.Println("解析JSON失败:", err) http.Error(w, "内部服务错误", http.StatusInternalServerError) return } // 校验数组非空后再取值 if len(tokenList) == 0 { fmt.Println("返回的token数组为空") http.Error(w, "内部服务错误", http.StatusInternalServerError) return } refreshToken := tokenList[0].RefreshToken fmt.Println("获取到的refresh_token:", refreshToken) // 此处可添加用refreshToken调用其他接口的逻辑 w.WriteHeader(resp.StatusCode) w.Write(respBody) }
注意事项
- 如果使用的Go版本高于1.16,推荐用
io.ReadAll替代ioutil.ReadAll,ioutil包在高版本已经被弃用,相关方法迁移到了os和io包下。 - 生产环境不要把敏感的token信息直接打印到日志中。
内容的提问来源于stack exchange,提问作者Jon Nicholson
相关产品推荐
相关产品推荐

