json.NewEncoder 和 json.NewDecoder 中的序列化/编码

V S*_*S X 1 rest json encode backend go

我正在尝试通过使用 Go 中的 gorilla mux 库构建不同的基本 REST API 来学习后端开发(遵循本教程

这是我迄今为止构建的代码:

package main

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

"github.com/gorilla/mux"
)

// Post represents single post by user
type Post struct {
Title  string `json:"title"`
Body   string `json:"body"`
Author User   `json:"author"`
}

// User is struct that represnets a user
type User struct {
FullName string `json:"fullName"`
Username string `json:"username"`
Email    string `json:"email"`
}

var posts []Post = []Post{}

func main() {
   router := mux.NewRouter()
   router.HandleFunc("/posts", addItem).Methods("POST")
   http.ListenAndServe(":5000", router)
}

func addItem(w http.ResponseWriter, req *http.Request) {
   var newPost Post
   json.NewDecoder(req.Body).Decode(&newPost)

   posts = append(posts, newPost)

   w.Header().Set("Content-Type", "application/json")
   json.NewEncoder(w).Encode(posts)
}
Run Code Online (Sandbox Code Playgroud)

然而,我真的很困惑到底发生了json.NewDecoder什么json.NewEncoder

据我了解,最终 REST API 中通过互联网进行的数据传输将以字节/二进制格式的形式进行(我猜是用 UTF-8 编码的?)。json.NewEncoder将 Go 数据结构转换为 JSON 字符串也是如此,并且json.NewDecoder执行相反的操作(如果我错了,请纠正我)。

  • 那么这里谁负责将这个 JSON 字符串转换为 UTF-8 编码以进行数据传输呢?这也是“什么”json.NewDecoder和“json.NewEncoder 做什么”的一部分吗?
  • 另外,如果这两个函数仅对 JSON 进行序列化/反序列化,那么为什么名称为编码器和解码器(编码不是总是与二进制数据转换相关?)。老实说,我对这些术语encoding以及serialization它们marshaling之间的区别感到非常困惑

有人可以解释一下在每个转换级别(json、二进制、内存数据结构)数据传输到底是如何发生的吗?

小智 6

首先,我们必须了解编码过程实际上并不意味着它转换types并返回type. 为您提供 JSON 表示形式的过程称为封送过程,可以通过调用json.Marshal 函数来完成。

另一方面,编码过程意味着我们想要获取任何内容的 JSON 编码type并将其写入(编码)到实现 io.Writer 接口的流上。正如我们所看到的,func NewEncoder(w io.Writer) *Encoder接收一个io.Writer接口作为参数并返回一个*json.Encoder对象。当调用该方法时encoder.Encode(),它会执行封送处理,然后将结果写入我们在创建新的 Encoder 对象时传递的 io.Writer。您可以在此处查看 json.Encoder.Encode() 的实现。

因此,如果您问谁对 http 流进行编码处理,答案是http.ResponseWriter. ResponseWriter 实现了 io.Writer 接口,当Encode()调用该方法时,编码器会将对象编组为 JSON 编码表示,然后调用func Write([]byte) (int, error)io.Writer 接口的契约方法,它将对对象进行写入过程http 流。

总之,我可以说 Marshal 和 Unmarshal 意味着我们想要获取任何类型的 JSON 表示形式,反之亦然。而 Encode 意味着我们要执行 Marshaling 过程,然后将结果写入(编码)到任何流对象。Decode 意味着我们要从任何流中获取(解码)一个 json 对象,然后进行 Unmarshaling 过程。