Golang如何合并HTTP JSON响应
Golang如何合并HTTP JSON响应 你好,
在Go语言中,通过for循环对一组链接执行HTTP GET请求,将每个HTTP JSON响应的输出合并到一个单一的数组对象中,最佳方法是什么?
for i := 0; i < len(servers.Sites); i++ {
req, err := http.NewRequest(http.MethodGet, servers.Sites[i].URLs, nil)
if err != nil {
log.Println(err)
}
}
我希望看到响应合并到一个对象中,就像这样,在“vm”对象下:
output := Output{
Success: true,
Vm: <JSON outputs here, each separated by comma>
}
更多关于Golang如何合并HTTP JSON响应的实战教程也可以访问 https://www.itying.com/category-94-b0.html
5 回复
是的。根据您的建议,它成功运行了。感谢您的帮助!
更多关于Golang如何合并HTTP JSON响应的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你是否已将 google.com 替换为一个实际会返回 JSON 数据的 URL?
感谢肖恩。我在我的笔记本电脑上的Go引擎中尝试了它,得到了:
{true [invalid character '<' looking for beginning of value]}
这是否符合你的需求?根据我在Go Playground上遇到的错误,看起来那个环境并未配置为允许发起网络请求,所以我不确定它是否准确。
在Go中合并多个HTTP JSON响应,可以通过以下方式实现:
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"sync"
)
type Output struct {
Success bool `json:"success"`
Vm []interface{} `json:"vm"`
}
type Site struct {
URLs string `json:"urls"`
}
type Servers struct {
Sites []Site `json:"sites"`
}
func fetchAndMergeJSON(servers Servers) (*Output, error) {
var (
wg sync.WaitGroup
mu sync.Mutex
output Output
)
output.Vm = make([]interface{}, 0, len(servers.Sites))
output.Success = true
for _, site := range servers.Sites {
wg.Add(1)
go func(url string) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
mu.Lock()
output.Success = false
mu.Unlock()
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
mu.Lock()
output.Success = false
mu.Unlock()
return
}
var jsonData interface{}
if err := json.Unmarshal(body, &jsonData); err != nil {
mu.Lock()
output.Success = false
mu.Unlock()
return
}
mu.Lock()
output.Vm = append(output.Vm, jsonData)
mu.Unlock()
}(site.URLs)
}
wg.Wait()
return &output, nil
}
func main() {
servers := Servers{
Sites: []Site{
{URLs: "https://api.example.com/data1"},
{URLs: "https://api.example.com/data2"},
{URLs: "https://api.example.com/data3"},
},
}
result, err := fetchAndMergeJSON(servers)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
jsonOutput, _ := json.MarshalIndent(result, "", " ")
fmt.Println(string(jsonOutput))
}
如果需要保持顺序,可以使用带缓冲的通道:
func fetchAndMergeJSONOrdered(servers Servers) (*Output, error) {
type result struct {
index int
data interface{}
err error
}
ch := make(chan result, len(servers.Sites))
var wg sync.WaitGroup
for i, site := range servers.Sites {
wg.Add(1)
go func(idx int, url string) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
ch <- result{index: idx, err: err}
return
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
ch <- result{index: idx, err: err}
return
}
var jsonData interface{}
if err := json.Unmarshal(body, &jsonData); err != nil {
ch <- result{index: idx, err: err}
return
}
ch <- result{index: idx, data: jsonData}
}(i, site.URLs)
}
wg.Wait()
close(ch)
output := &Output{
Success: true,
Vm: make([]interface{}, len(servers.Sites)),
}
for res := range ch {
if res.err != nil {
output.Success = false
}
if res.data != nil {
output.Vm[res.index] = res.data
}
}
return output, nil
}
对于需要处理特定JSON结构的情况:
type VMData struct {
ID int `json:"id"`
Name string `json:"name"`
// 其他字段...
}
func fetchStructuredJSON(servers Servers) (*Output, error) {
var (
wg sync.WaitGroup
mu sync.Mutex
output Output
)
output.Vm = make([]VMData, 0, len(servers.Sites))
output.Success = true
for _, site := range servers.Sites {
wg.Add(1)
go func(url string) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
mu.Lock()
output.Success = false
mu.Unlock()
return
}
defer resp.Body.Close()
var vmData VMData
if err := json.NewDecoder(resp.Body).Decode(&vmData); err != nil {
mu.Lock()
output.Success = false
mu.Unlock()
return
}
mu.Lock()
output.Vm = append(output.Vm.([]VMData), vmData)
mu.Unlock()
}(site.URLs)
}
wg.Wait()
return &output, nil
}

