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

问题描述

我正在尝试通过在Go中使用gorilla mux库构建各种基本的REST API来学习后端开发(此tutorial之后)

这是我到目前为止构建的代码:

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)
}

但是,我对json.NewDecoderjson.NewEncoder部分到底发生了什么感到非常困惑。

据我了解,最终以REST API通过Internet进行的数据传输将以字节/二进制格式(我猜是UTF-8编码)的形式发生。因此,json.NewEncoder会将Go数据结构转换为JSON字符串,而json.NewDecoder则相反(如果我错了,请纠正我)。

  • 因此,谁负责将JSON字符串转换为UTF-8? 编码进行数据传输?这也是json.NewDecoderjson.NewEncoder的一部分吗 会吗?
  • 此外,如果这两个函数仅是序列化/反序列化 与JSON之间的交互,为什么使用编码器和解码器的名称(不编码) 总是与二进制数据转换有关?)。老实说,我对术语encodingserializationmarshaling以及它们之间的区别感到困惑

有人能解释一下每个转换级别(json,二进制,内存中的数据结构)在这里的数据传输是如何发生的吗?

解决方法

  1. 通过调用json.Encoder产生的json.NewEncoder直接以UTF-8形式产生其输出。无需转换。 (实际上,Go没有与UTF-8编码的字节序列不同的文本数据表示形式,即使string只是底层的不可变字节数组。)

  2. Go使用术语 encode 进行序列化,使用 decode 进行反序列化,无论序列化形式是二进制还是文本形式。不要过多考虑术语-将 encode seralise 视为同义词。

,

首先,我们必须了解,编码过程实际上并不意味着它会翻译types并返回type的JSON表示形式。为您提供JSON表示的过程称为封送处理(Marshaling process),可以通过调用gray icon来完成。

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

因此,如果您询问谁对http流进行编码处理,答案是http.ResponseWriter。 ResponseWriter实现io.Writer接口,并且在调用Encode()方法时,编码器会将对象编组为JSON编码表示形式,然后调用func Write([]byte) (int,error),它是io.Writer的协定方法。界面,它将完成对HTTP流的写入过程。

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...