【问题标题】:Golang POST request in JSON format from a csv file来自 csv 文件的 JSON 格式的 Golang POST 请求
【发布时间】:2020-06-20 20:46:38
【问题描述】:

所以我正在尝试将 JSON 格式的 csv 文件发布到 Golang 中的网站。我已经成功发布了一个单一的 JSON 文件。但是,这不是我希望我的程序的目的。基本上,我正在尝试为网站创建一个帐户生成器。我希望能够一次生成多个帐户。我觉得最好的方法是使用 csv 文件。

我尝试使用 encoding/csv 来读取 csv 文件,然后将其编组为 JSON。另外,ioutil.ReadFile()。但是,该站点的响应是,“名字是必填字段,姓氏是必填字段”等。因此,这显然意味着 csv 数据不会进入 JSON 格式。我将在下面使用 ioutil.ReadFile() 显示我的代码。

func main() {
file, _ := ioutil.ReadFile("accounts.csv")

    jsonConv, _ := json.Marshal(file)

    client := http.Client{}

    req, err := http.NewRequest("POST", "websiteUrlHere", bytes.NewBuffer(jsonConv))
    req.Header.Add("cookie", `"really long cookie goes here"`)
    req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36")
    req.Header.Set("content-type", "application/json")

    resp, err := client.Do(req)
    if err != nil {
        fmt.Print(err)
    }
    defer resp.Body.Close()
}

(^这只是一个sn-p的代码)。

我对这一切还是很陌生,所以如果问题缺少任何内容,请理解。我也寻找过类似的问题,但我发现的只是结构的使用。我认为这不适用于此,因为目标是一次创建无限帐户。

希望以上内容就足够了。谢谢。

【问题讨论】:

  • ioutil.ReadFile 只是从文件中读取原始数据。您需要将其实际解析为数据类型,然后以 json 格式输出该数据。谷歌如何将 csv 文件读入结构,然后你可以在同一个结构上使用 json.Marshal。

标签: json csv go


【解决方案1】:

您的代码的问题实际上是您试图将文件转换为字节:

file, _ := ioutil.ReadFile("accounts.csv")

...然后您再次尝试将该字节片段转换为 JSON 字节:

jsonConv, _ := json.Marshal(file)

文件的文本内容作为字节切片存储在变量file 中,然后该字节切片(字节形式的文件内容)被转换为 JSON 字节数组。所以你基本上是在发送一个 JSON 数字数组......不好。

这里的正常流程是获取 file 字节,然后从中创建一个 Go 结构。一旦你的 Go 对象就位,那么你将编组为 JSON。这会将 Go 对象转换为 JSON 文本格式之后的字节切片。

所以您缺少的是 Go 结构中间步骤,但您还应该记住,使用 json.Marshal() 将 Go 结构转换为 JSON 字节只会显示导出的字段。此外,通常您应该使用 struct 标签来准确自定义字段的显示方式。

您最好的选择就是坚持使用 JSON,忘记 CSV。在您自己的代码示例中,您正在获取 CSV,然后尝试将其转换为 JSON……那么,只需使用 JSON。

如果您想发送多个帐户,只需将您的 Go 结构设为一个切片,该切片将编组为一个 JSON 数组,这基本上就是您想要做的。最终结果将是一个 JSON 帐户数组。这是一个简单的例子:

package main

import (
    "fmt"
    "encoding/json"
)

type Account struct {
    Username string `json:"username"`
    Email string `json:"email"`
}

type AccountsRequest struct {
    Accounts []Account `json:"accounts"`
}

func main() {
    //gather account info
    acct1 := Account{Username: "tom", Email: "tom@example.com"}
    acct2 := Account{Username: "dick", Email: "dick@example.com"}
    acct3 := Account{Username: "harry", Email: "harry@example.com"}
    
    //create request
    acctsReq := AccountsRequest{Accounts: []Account{acct1, acct2, acct3}}
    
    //convert to JSON bytes/data
    //jsonData, _ := json.Marshal(acctsReq)
    
    //debug/output
    jsonDataPretty, _ := json.MarshalIndent(acctsReq, "", "  ")
    fmt.Println(string(jsonDataPretty))
    
    //send request with data
    //...
}

可在操场上运行 here

关键是结构已设置好并准备就绪,结构标签确定 JSON 字段名称将是什么(即每个帐户的 usernameemail 以及整个帐户数组的 accounts )。

希望对您有所帮助。如果您需要更具体的帮助,请发表评论。

【讨论】:

  • 谢谢,这对个人使用非常有用。但是,我的目标是将它分发给我的大约 10 个朋友。他们不知道如何编码,所以我觉得 csv/json 文件会好得多。您认为您的方法在没有代码和 exe 等的情况下仍然可以使用?
  • 这是给你的服务器端的。所以你看到我在 main 开始时在哪里创建 3 个帐户了吗?好吧,这就是您解析他们的 CSV 并为每一行创建其中一个结构的地方。对于客户端,您只需编写一个带有接受 csv 文件上传的表单输入字段的 html 文件。然后他们上传 CSV,你有一个 Go 服务器监听该请求,解析文件并创建这些结构。
【解决方案2】:

您需要先解析CSV文件并将其转换为您想要的列表:

package main


func main() {
   file, err := os.Open("file.csv")
   if err != nil {
      log.Fatal("failed opening file because: %s", err.Error())
   }
   r := csv.NewReader(file)

   records, err := r.ReadAll()
   if err != nil {
      log.Fatal(err)
   }
   fmt.Print(records)
}

上面的代码将列表解析成一个[][]字符串数组。您现在需要遍历该数组并将其转换为页面所需的 json 对象。然后就可以发送了。您可以在此处阅读有关 csv 包的更多信息:https://golang.org/pkg/encoding/csv/

忠告:永远不要忽略错误,它们可能会为您提供有用的信息。

【讨论】:

    猜你喜欢
    • 2019-05-10
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多