Golang从URL字符串读取JSON数据的方法

Golang从URL字符串读取JSON数据的方法 我想从这个链接返回的字符串构建一个JSON对象。我写了下面的代码,它能够正确读取URL并获取字符串,但在构建JSON对象时失败了,没有返回任何内容!

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

type Product struct {
	ProductId   string `json:"id"`
	ProductName string `json:"description"`
}

func main() {
	url := "https://script.googleusercontent.com/macros/echo?user_content_key=WBSJPDNSN6X1FCYeXsR6TDaDval0vdvmSoMmXFhGbt5sfK0ia80Dp7kPD27GLpZbYz8vrwfDiUecI2oGMjEtgfL5o8Da25T1m5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnGb6k9xaGtOX6M1tIiG811CRpk9nXl8ZKS7UJTno1dvQXMe1kqfAj8WxsSkLor-EqzOmbnRGq-tk&lib=M0B6GXYh0EOYMkP7qr1Xy9xw8GuJxFqGH"
	resp, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}

	defer resp.Body.Close()

	htmlData, err := ioutil.ReadAll(resp.Body) //<--- here!

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// print out
	fmt.Println(string(htmlData))

	var product Product
	json.Unmarshal([]byte(string(htmlData)), &product)

	fmt.Printf("ID: %s, Description: %s", product.ProductId, product.ProductName)
}

输出:

{"user":[{"ProductId":1,"ProductName":"Helmet"},{"ProductId":2,"ProductName":"Glove"},{"ProductId":3,"ProductName":"Detecttor"}]}
ID: , Description:

更多关于Golang从URL字符串读取JSON数据的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我明白了:

  1. 反序列化的目标结构体必须与数据匹配,
type Data struct {
   User []Product `json:"user"`
}
  1. 字段类型应该匹配,所以 ProductID 应该是 uint
  2. 输出中得到的 json 操作应该与使用的标签匹配
type Product struct {
    ProductId   uint `json:"ProductId"`
    ProductName string `json:"ProductName"`
}

所以,一个可运行的代码是:

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

type Data struct {
	User []Product `json:"user"`
}
type Product struct {
	ProductId   uint   `json:"ProductId"`
	ProductName string `json:"ProductName"`
}

func main() {
	url := "https://script.googleusercontent.com/macros/echo?user_content_key=WBSJPDNSN6X1FCYeXsR6TDaDval0vdvmSoMmXFhGbt5sfK0ia80Dp7kPD27GLpZbYz8vrwfDiUecI2oGMjEtgfL5o8Da25T1m5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnGb6k9xaGtOX6M1tIiG811CRpk9nXl8ZKS7UJTno1dvQXMe1kqfAj8WxsSkLor-EqzOmbnRGq-tk&amp;lib=M0B6GXYh0EOYMkP7qr1Xy9xw8GuJxFqGH"
	resp, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}

	defer resp.Body.Close()

	htmlData, err := ioutil.ReadAll(resp.Body) 

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// print out
	fmt.Println(string(htmlData))

	//var product Product
	var data Data
	json.Unmarshal([]byte(string(htmlData)), &data)

	fmt.Println(data)
	fmt.Println(data.User)
	fmt.Println(data.User[0])
	fmt.Printf("id: %v, description: %s", data.User[0].ProductId, data.User[0].ProductName)
}

更多关于Golang从URL字符串读取JSON数据的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的代码问题在于JSON结构不匹配。URL返回的是一个包含user数组的JSON对象,而你的Product结构体试图直接解析这个对象。你需要创建一个包装结构体来匹配实际的JSON结构。

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type Product struct {
	ProductId   string `json:"ProductId"`
	ProductName string `json:"ProductName"`
}

type Response struct {
	User []Product `json:"user"`
}

func main() {
	url := "https://script.googleusercontent.com/macros/echo?user_content_key=WBSJPDNSN6X1FCYeXsR6TDaDval0vdvmSoMmXFhGbt5sfK0ia80Dp7kPD27GLpZbYz8vrwfDiUecI2oGMjEtgfL5o8Da25T1m5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnGb6k9xaGtOX6M1tIiG811CRpk9nXl8ZKS7UJTno1dvQXMe1kqfAj8WxsSkLor-EqzOmbnRGq-tk&lib=M0B6GXYh0EOYMkP7qr1Xy9xw8GuJxFqGH"
	
	resp, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	var response Response
	err = json.Unmarshal(body, &response)
	if err != nil {
		log.Fatal(err)
	}

	for _, product := range response.User {
		fmt.Printf("ID: %s, Description: %s\n", product.ProductId, product.ProductName)
	}
}

如果你只需要解析单个产品而不是数组,可以这样修改:

type Response struct {
	User Product `json:"user"`
}

func main() {
	// ... 前面的代码相同
	
	var response Response
	err = json.Unmarshal(body, &response)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("ID: %s, Description: %s\n", response.User.ProductId, response.User.ProductName)
}

关键点是JSON标签必须与实际的JSON字段名完全匹配。在你的例子中,JSON使用的是ProductIdProductName,而不是iddescription

回到顶部