apaas.dev
7 November 2022
这是一个非常常见的任务:编码 JSON 并将其发送到服务器,在服务器上解码 JSON,反之亦然。令人惊讶的是,关于如何做到这一点的现有资源并不是很清楚。因此,让我们来看看每个案例,对于以下简单的 User 对象:
type User struct{ Id string Balance uint64 }
在 POST/PUT 请求的正文中发送 JSON
让我们从最棘手的开始:Go 的 http.Request 的主体是一个 io.Reader,如果你有一个结构,它就不太适合 - 你需要先编写结构,然后将其复制到阅读器。
func main() { u := User{Id: "US123", Balance: 8} b := new(bytes.Buffer) json.NewEncoder(b).Encode(u) res, _ := http.Post("https://httpbin.org/post", "application/json; charset=utf-8", b) io.Copy(os.Stdout, res.Body) }
在服务器上解码 JSON
假设您希望客户端将 JSON 数据发送到服务器。很简单,用 json.NewDecoder(r.Body).Decode(&u) 解码它。以下是错误处理的样子:
func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { var u User if r.Body == nil { http.Error(w, "Please send a request body", 400) return } err := json.NewDecoder(r.Body).Decode(&u) if err != nil { http.Error(w, err.Error(), 400) return } fmt.Println(u.Id) }) log.Fatal(http.ListenAndServe(":8080", nil)) }
在服务器响应中编码 JSON
与上述相反 - 调用 json.NewEncoder(w).Encode(&u) 将 JSON 写入服务器。
func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { u := User{Id: "US123", Balance: 8} json.NewEncoder(w).Encode(u) }) log.Fatal(http.ListenAndServe(":8080", nil)) }
从服务器读取 JSON 响应。
这次您将在发出请求后读取客户端中的响应正文。
func main() { u := User{Id: "US123", Balance: 8} b := new(bytes.Buffer) json.NewEncoder(b).Encode(u) res, _ := http.Post("https://httpbin.org/post", "application/json; charset=utf-8", b) var body struct { // httpbin.org sends back key/value pairs, no map[string][]string Headers map[string]string `json:"headers"` Origin string `json:"origin"` } json.NewDecoder(res.Body).Decode(&body) fmt.Println(body) }
而已!我希望它对你有很大帮助。请注意,我们只需要对字节数组的响应进行一次编码/解码 - 在其他所有情况下,我们都将其直接传递给读取器/写入器,这是 Go 和接口的真正优点之一 - 在大多数情况下,它是真的很容易传递流,而不必处理中间步骤。
- 登录 发表评论