美文网首页Gopher
Go -- 定制Marshal JSON的部分字段

Go -- 定制Marshal JSON的部分字段

作者: 李书文 | 来源:发表于2019-05-15 10:01 被阅读0次

起因:从MongoDB中获取的时间戳字段在转换成JSON时不符合需求。需要对这个字段定制一下,转换成需要的字符串。

解决方案:

  • 最直接的方案就是,对让对应的struct实现MarshalJSON这个方法,自己生成整个JSON字符串, 碰到需要定制的字段,再自行更改。
    示例代码如下:Code From
func (this Stuff) MarshalJSON() ([]byte, error) {
    buffer := bytes.NewBufferString("{")
    length := len(this)
    count := 0
    for key, value := range this {
        jsonValue, err := json.Marshal(value)
        if err != nil {
            return nil, err
        }
        buffer.WriteString(fmt.Sprintf("\"%d\":%s", key, string(jsonValue)))
        count++
        if count < length {
            buffer.WriteString(",")
        }
    }
    buffer.WriteString("}")
    return buffer.Bytes(), nil
}
  • 还有一种方法就是使用辅助struct,这样写起来可能比上面的轻松一些。
    示例代码如下:Code From
type MyUser struct {
    ID       int64     `json:"id"`
    Name     string    `json:"name"`
    LastSeen time.Time `json:"lastSeen"`
}

func (u *MyUser) MarshalJSON() ([]byte, error) {
    return json.Marshal(&struct {
        ID       int64  `json:"id"`
        Name     string `json:"name"`
        LastSeen int64  `json:"lastSeen"`
    }{
        ID:       u.ID,
        Name:     u.Name,
        LastSeen: u.LastSeen.Unix(),
    })
}
  • 不过如果字段很多时候,就可能要写很长,但我们只需要更改某些字段。那么可以使用别名struct,写出更简短的代码。为什么要为struct起个别名呢?因为如果直接使用原来的struct,那么辅助的struct也会继承原来的MarshalJSON方法,这样就成为一个无限循环了。
    示例代码如下:Code From
type MyUser struct {
    ID       int64     `json:"id"`
    Name     string    `json:"name"`
    LastSeen time.Time `json:"lastSeen"`
}

func (u *MyUser) MarshalJSON() ([]byte, error) {
    type Alias MyUser
    return json.Marshal(&struct {
        LastSeen int64 `json:"lastSeen"`
        *Alias
    }{
        LastSeen: u.LastSeen.Unix(),
        Alias:    (*Alias)(u),
    })
}

注意⚠️
MarshalJSON这个方法返回的是[]byte,所以如果想打印出来或者使用字符串,需要进行转换string(result),否则就会出现链接中的问题

相关文章

网友评论

    本文标题:Go -- 定制Marshal JSON的部分字段

    本文链接:https://www.haomeiwen.com/subject/eeuuaqtx.html