Serialization 具有io.Reader的Golang结构无法序列化

Serialization 具有io.Reader的Golang结构无法序列化,serialization,go,deserialization,Serialization,Go,Deserialization,我试图将下面的struct序列化为byte[]以将其存储到DB中,然后在从DB中读取它的同时,对其进行反序列化 type Response struct { Headers map[string][]string Body io.Reader Status int } 下面是我如何创建响应对象并为其设置值的代码 resp := new(Response) resp.Body = bytes.NewReader(outBytes) //outBytes is by

我试图将下面的struct序列化为
byte[]
以将其存储到DB中,然后在从DB中读取它的同时,对其进行反序列化

type Response struct {
    Headers map[string][]string
    Body    io.Reader
    Status  int
}
下面是我如何创建响应对象并为其设置值的代码

resp := new(Response)
resp.Body = bytes.NewReader(outBytes) //outBytes is byte[]
resp.Headers.SetKeyValue("Content-Type", "text/json") //SetKeyValue is the method created for adding headers
resp.Headers.SetKeyValue("Url-Type", "broker")
resp.Status = 200
我正在使用
json.Marshal()
序列化
resp
对象,如下所示

b, _ := json.Marshal(resp)
下面是我用来反序列化的代码

var r Response
r.Body = &bytes.Buffer{}
json.Unmarshal(b,&r)
问题在于反序列化,我无法获取
resp.Body
对象。尽管设置了body object(参见上文),但它始终为
nil
或空白。我可以从反序列化中获取结构的
标题
状态
字段,但不能从
正文
中获取

我知道有一些东西需要处理
Body
字段,它是一个
io.Reader

任何帮助都会非常好。

我正在使用
“encoding/json”
包:

因为我可以使用http.ResponseWriter发送JSON响应。以下两个函数可用于发送JSON和从正文中读取JSON:

// GetJSONContent returns the JSON content of a request
func GetJSONContent(v interface{}, r *http.Request) error {
    defer r.Body.Close()
    return json.NewDecoder(r.Body).Decode(v)
}

// JSONWithHTTPCode Json Output with an HTTP code
func JSONWithHTTPCode(w http.ResponseWriter, d interface{}, code int) {
    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    w.WriteHeader(code)
    if d != nil {
        err := json.NewEncoder(w).Encode(d)
        if err != nil {
            panic(err)
        }
    }
}
然后在处理程序中,只需按如下方式使用这些func:

// Handler handler
func Handler(w http.ResponseWriter, r *http.Request) {
        s := YourStruct{}
        err = GetJSONContent(s, r) 
        if err != nil {
            panic(err)
        }
        return
    }

    JSONWithHTTPCode(w, s, http.StatusOK)
}
希望它有帮助

我正在使用
编码/json”
包:

因为我可以使用http.ResponseWriter发送JSON响应。以下两个函数可用于发送JSON和从正文中读取JSON:

// GetJSONContent returns the JSON content of a request
func GetJSONContent(v interface{}, r *http.Request) error {
    defer r.Body.Close()
    return json.NewDecoder(r.Body).Decode(v)
}

// JSONWithHTTPCode Json Output with an HTTP code
func JSONWithHTTPCode(w http.ResponseWriter, d interface{}, code int) {
    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    w.WriteHeader(code)
    if d != nil {
        err := json.NewEncoder(w).Encode(d)
        if err != nil {
            panic(err)
        }
    }
}
然后在处理程序中,只需按如下方式使用这些func:

// Handler handler
func Handler(w http.ResponseWriter, r *http.Request) {
        s := YourStruct{}
        err = GetJSONContent(s, r) 
        if err != nil {
            panic(err)
        }
        return
    }

    JSONWithHTTPCode(w, s, http.StatusOK)
}

希望对您有所帮助。

简短回答:JSON marshaller不会使用
Read()
函数从io.Reader读取字符串。您可以使用实现
封送处理程序
接口的类型,而不是使用
io.Reader

马歇尔勒的工作原理: 封送处理递归地遍历值v。如果遇到的值实现了
Marshaler
接口,并且不是nil指针,则Marshal将调用其
MarshalJSON
方法来生成JSON。如果不存在MarshalJSON方法,但该值实现了
encoding.textmasharler
,则Marshal将调用其
MarshalText
方法。nil指针异常并不是严格必需的,但它模拟了解组JSON行为中类似的必需异常

否则,封送处理将使用以下依赖于类型的默认编码:

  • 布尔值编码为JSON布尔值
  • 浮点、整型和数值编码为JSON数字
实施 这就是你可以做的

type Response struct {
    Headers map[string][]string
    Body    *JSONReader
    Status  int
}

type JSONReader struct {
    *bytes.Reader
}

func NewJSONReader(outBytes []byte) *JSONReader {
    jr := new(JSONReader)
    jr.Reader = bytes.NewReader(outBytes)
    return jr
}

func (js JSONReader) MarshalJSON() ([]byte, error) {
    data, err := ioutil.ReadAll(js.Reader)
    if err != nil {
        return nil, err
    }
    data = []byte(`"` + string(data) + `"`)
    return data, nil
}

// UnmarshalJSON sets *jr to a copy of data.
func (jr *JSONReader) UnmarshalJSON(data []byte) error {
    if jr == nil {
        return errors.New("json.JSONReader: UnmarshalJSON on nil pointer")
    }
    if data == nil {
        return nil
    }
    data = []byte(strings.Trim(string(data), "\""))
    jr.Reader = bytes.NewReader(data)
    return nil
}

下面是一个关于实现和示例用法的go Playerly链接:

简短回答:JSON marshaller不会使用
Read()
函数从io.Reader读取字符串。您可以使用实现
封送处理程序
接口的类型,而不是使用
io.Reader

马歇尔勒的工作原理: 封送处理递归地遍历值v。如果遇到的值实现了
Marshaler
接口,并且不是nil指针,则Marshal将调用其
MarshalJSON
方法来生成JSON。如果不存在MarshalJSON方法,但该值实现了
encoding.textmasharler
,则Marshal将调用其
MarshalText
方法。nil指针异常并不是严格必需的,但它模拟了解组JSON行为中类似的必需异常

否则,封送处理将使用以下依赖于类型的默认编码:

  • 布尔值编码为JSON布尔值
  • 浮点、整型和数值编码为JSON数字
实施 这就是你可以做的

type Response struct {
    Headers map[string][]string
    Body    *JSONReader
    Status  int
}

type JSONReader struct {
    *bytes.Reader
}

func NewJSONReader(outBytes []byte) *JSONReader {
    jr := new(JSONReader)
    jr.Reader = bytes.NewReader(outBytes)
    return jr
}

func (js JSONReader) MarshalJSON() ([]byte, error) {
    data, err := ioutil.ReadAll(js.Reader)
    if err != nil {
        return nil, err
    }
    data = []byte(`"` + string(data) + `"`)
    return data, nil
}

// UnmarshalJSON sets *jr to a copy of data.
func (jr *JSONReader) UnmarshalJSON(data []byte) error {
    if jr == nil {
        return errors.New("json.JSONReader: UnmarshalJSON on nil pointer")
    }
    if data == nil {
        return nil
    }
    data = []byte(strings.Trim(string(data), "\""))
    jr.Reader = bytes.NewReader(data)
    return nil
}
下面是一个go Playerd链接,其中包含实现和示例用法:

概述 是一个接口,因此无法封送。每个封送结构属性都必须实现要封送的接口。您可以声明自己的封送处理程序包装结构来封送来自
字节的数据。Reader

为什么接口不能被封送? Go中的接口提供了一种指定对象行为的方法:如果有什么东西可以做到这一点,那么可以在这里使用它。相反,Go的结构是字段的类型化集合。它们对于将数据分组形成记录很有用。Go支持在结构类型而不是接口类型上定义的方法

实施 概述 是一个接口,因此无法封送。每个封送结构属性都必须实现要封送的接口。您可以声明自己的封送处理程序包装结构来封送来自
字节的数据。Reader

为什么接口不能被封送? Go中的接口提供了一种指定对象行为的方法:如果有什么东西可以做到这一点,那么可以在这里使用它。相反,Go的结构是字段的类型化集合。它们对于将数据分组形成记录很有用。Go支持在结构类型而不是接口类型上定义的方法

实施
您使用了错误的结构,
io。Reader
仅为and接口和
字节。Reader
没有任何导出属性,因此
Body
为空。您应该将
Body
的类型更改为对您有帮助的类型,如
string
,或者您可以只使用
[]byte
谢谢,我已将Body字段定义为可以从任何流读取数据的流,我无法更改字段类型。我不明白为什么有人提出我的问题。如果
Headers
是一个映射,那么它上怎么会有函数“SetKeyValue”?我定义了一个类型Headers映射[HeaderKey][]字符串,Headers是Headers类型,那么该方法就是这种类型。为了让我的问题小一些,我把它的简短版本放在这里。您可以认为该方法只是添加标题的方法。您使用了错误的结构,
io。Reader
只是and接口和
字节。Reader
没有任何导出属性,因此
Body
是blan