Golang中从HTTP请求获取数据的"最佳"方法是什么

Golang中从HTTP请求获取数据的"最佳"方法是什么 大家好,我正在使用正则表达式获取如下数据,但我认为这不是获取这些信息的最佳方式。

{"transactions": [{
    "bytes":null,
    "length":1,
    "time":"1653228731.000000",
    "name":"Test",
    "status":"success",
    "transfers":[{
          "id":"3",
          "amount":3930,
          "approval":false
      }
}

使用 getXML 函数将数据作为字符串获取,然后使用正则表达式选择每个特定的信息。

func getXML(url string) (string, error) {
	resp, err := http.Get(url)
	if err != nil {
		return "", fmt.Errorf("GET error: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Status error: %v", resp.StatusCode)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("Read body: %v", err)
	}

	return string(data), nil
}

正则表达式示例:regexp.MustCompile(“name”:"\s*(.?)\s")

嗯,我觉得这不是获取这些信息最常见和高效的方式。可能存在着类似 GetEnv("name") 的东西可以为 HTTP 请求做这件事。

有人能帮助我吗?


更多关于Golang中从HTTP请求获取数据的"最佳"方法是什么的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

在我看来这仍然是有效的JSON…

更多关于Golang中从HTTP请求获取数据的"最佳"方法是什么的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,你说得对!我误解了XML和JSON的含义。谢谢你。

  1. 这个示例看起来不像是XML,更像是JSON。
  2. 我们会分别使用 encoding/xmlencoding/json 将数据解析到结构体中。

我实际编写的方式看起来确实像 JSON,但从 HTTP 获取到的字符串却是这样的(没有换行和空格):

{"transactions",[{"bytes":null,"length":1,"time":"1653228731.000000","name":"Test","status":"success","transfers":[{"id":"3","amount":3930,"approval":false}}

XML 看起来像 XHTML:

<?xml version="1.0" encoding="UTF-8"?>
<transactions>
    <length value="1"/>
    <bytes/>
    <time value="1653228731.000000"/>
    ...
</transactions>

JSON 看起来像:

{key: "value", key2: "value2", key3: [1, 2, 3, 4]}

在Golang中处理HTTP响应数据时,使用JSON解析比正则表达式更可靠和高效。对于你提供的JSON数据,应该使用标准库的encoding/json包。

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

type Transfer struct {
    ID       string `json:"id"`
    Amount   int    `json:"amount"`
    Approval bool   `json:"approval"`
}

type Transaction struct {
    Bytes     interface{} `json:"bytes"`
    Length    int         `json:"length"`
    Time      string      `json:"time"`
    Name      string      `json:"name"`
    Status    string      `json:"status"`
    Transfers []Transfer  `json:"transfers"`
}

type Response struct {
    Transactions []Transaction `json:"transactions"`
}

func getTransactions(url string) (*Response, error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, fmt.Errorf("GET error: %v", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("Status error: %v", resp.StatusCode)
    }

    var response Response
    decoder := json.NewDecoder(resp.Body)
    if err := decoder.Decode(&response); err != nil {
        return nil, fmt.Errorf("JSON decode error: %v", err)
    }

    return &response, nil
}

func main() {
    url := "http://example.com/api/data"
    response, err := getTransactions(url)
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }

    // 访问数据示例
    for _, transaction := range response.Transactions {
        fmt.Printf("Name: %s, Status: %s\n", transaction.Name, transaction.Status)
        for _, transfer := range transaction.Transfers {
            fmt.Printf("  Transfer ID: %s, Amount: %d\n", transfer.ID, transfer.Amount)
        }
    }
}

如果数据量较大,可以使用流式解析:

func processLargeResponse(url string) error {
    resp, err := http.Get(url)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    decoder := json.NewDecoder(resp.Body)
    
    // 读取起始标记
    if _, err := decoder.Token(); err != nil {
        return err
    }
    
    // 解析每个transaction
    for decoder.More() {
        var transaction Transaction
        if err := decoder.Decode(&transaction); err != nil {
            return err
        }
        fmt.Printf("Processing: %s\n", transaction.Name)
    }
    
    return nil
}

对于需要从嵌套JSON中提取特定字段的情况,可以使用匿名结构体:

func extractSpecificFields(url string) ([]string, error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    var data struct {
        Transactions []struct {
            Name   string `json:"name"`
            Status string `json:"status"`
        } `json:"transactions"`
    }
    
    if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
        return nil, err
    }
    
    var names []string
    for _, t := range data.Transactions {
        names = append(names, t.Name)
    }
    
    return names, nil
}

这种方法比正则表达式更安全,能正确处理JSON转义字符、嵌套结构和数据类型转换。

回到顶部