pra*_*yay 1 serialization go deserialization
我试图将struct下面的序列化为byte []以将其存储到DB中,然后在从DB中读取它时我将其反序列化.
type Response struct {
Headers map[string][]string
Body io.Reader
Status int
}
Run Code Online (Sandbox Code Playgroud)
下面是我如何创建响应对象并为其设置值的代码.
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
Run Code Online (Sandbox Code Playgroud)
我正在使用json.Marshal()来序列化resp对象,如下所示.
b, _ := json.Marshal(resp)
Run Code Online (Sandbox Code Playgroud)
下面是代码,我用来反序列化.
var r Response
r.Body = &bytes.Buffer{}
json.Unmarshal(b,&r)
Run Code Online (Sandbox Code Playgroud)
问题是反序列化,我无法获得resp.Body对象.尽管设置了体对象,但它总是为零或空白(见上文).我可以从反序列化而不是Body获取结构的Headers和status字段.
我知道有一些东西需要处理Body字段,它是一个io.Reader.
任何帮助都会非常棒.
Read()简答: JSON marshaller不会使用函数从io.Reader读取字符串.而不是使用io.Reader您可以使用实现Marshaler接口的类型.
Marshaller的工作原理:
Marshal以递归方式遍历值v.如果遇到的值实现了Marshaler接口并且不是nil指针,则Marshal会调用其MarshalJSON方法来生成JSON.如果没有MarshalJSON方法,但值实现了encoding.TextMarshaler,Marshal会调用它的MarshalText方法.nil指针异常不是绝对必要的,但在UnmarshalJSON的行为中模仿了类似的必要异常.
否则,Marshal使用以下type-dependent默认编码:
实现 这就是你可以做的
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
}
Run Code Online (Sandbox Code Playgroud)
这是一个go操场链接,其中包含实现和示例用法:link