Go 中时间类型字段的 JSON 序列化和反序列化的处理技巧

我主要从其他博主教程那里学来的技巧:smile::laughing:

主要的思路就是(我的理解):

通过重写MarshalJSONUnmarshalJSON接口,结构体struct的嵌套,把不是时间类型字段的保留,是时间类型字段的变为string类型,生成临时的Temp结构体,然后对时间类型字段单独处理。代码如下:

抽出数据表常用字段:
//定义一些表默认的字段
type Model struct {
    ID              int       `gorm:"primary_key" json: "id"`
    CreateTime      time.Time `json:"create_time"`
    UpdateTime      time.Time `json:"update_time"`
    CreateOperator  string    `json:"create_operator"`
    UpdateOperator  string    `json:"update_operator"`
    OperationReason string    `json:"operation_reason"`
}
重写MarshalJSON接口即结构体转json字符串:
// MarshalJSON 为Model类型实现自定义的MarshalJSON方法
func (m *Model) MarshalJSON() ([]byte, error) {
    type Temp Model // 定义与Model字段一致的新类型
    return json.Marshal(struct {
        CreateTime string `json:"create_time"`
        UpdateTime string `json:"update_time"`
        *Temp // 避免直接嵌套Model进入死循环
    }{
        CreateTime: m.CreateTime.Format(setting.LayOut),
        UpdateTime: m.UpdateTime.Format(setting.LayOut),
        Temp:       (*Temp)(m),//Model类型指针变为Temp类型指针,下同
    })
}
重写UnmarshalJSON接口即转json字符串为结构体:
// UnmarshalJSON 为Model类型实现自定义的UnmarshalJSON方法
//这个我没验证。
func (m *Model) UnmarshalJSON(data []byte) error {
    type Temp Model // 定义与Model字段一致的新类型
    ot := struct {
        CreateTime string `json:"create_time"`
        UpdateTime string `json:"update_time"`
        *Temp // 避免直接嵌套Model进入死循环
    }{
        Temp: (*Temp)(m),
    }
    if err := json.Unmarshal(data, &ot); err != nil {
        return err
    }
    var err error
    m.CreateTime, err = time.Parse(setting.LayOut, ot.CreateTime)
    if err != nil {
        return err
    }
    m.UpdateTime, err = time.Parse(setting.LayOut, ot.UpdateTime)
    if err != nil {
        return err
    }
    return nil
}
从而在需要用到的地方有时间类型字段的struct结构体中,嵌套Model结构体就可以(注:CreateTimeUpdateTime根据自己需要改变,这里只是给个例子)如:
type Student struct {
    Model
    Name   string `json:"name"`
    Age int    `json:"age"`
}

然后对Student结构体,正常序列化和饭序列化,即可。:laughing:。。我目前看到的解决办法,有其他好方法的留言啊。(Go新手上路)

本作品采用《CC 协议》,转载必须注明作者和本文链接
一切皆自学
讨论数量: 1
type Student struct {
    Model
    Name   string `json:"name"`
    Age int    `json:"age"`
}

这里这样貌似有问题,序列化后会丢失name 和 age的值,匿名嵌套的问题

stackoverflow.com/questions/532289...

我们是用这样写的

type Time time.Time

const (
    timeFormat = "2006-01-02 15:04:05"
)

func (t *Time) UnmarshalJSON(data []byte) (err error) {
    now, err := time.ParseInLocation(`"`+timeFormat+`"`, string(data), time.Local)
    *t = Time(now)
    return
}

func (t Time) MarshalJSON() ([]byte, error) {
    b := make([]byte, 0, len(timeFormat)+2)
    b = append(b, '"')
    b = time.Time(t).AppendFormat(b, timeFormat)
    b = append(b, '"')
    return b, nil
}

func (t Time) String() string {
    return time.Time(t).Format(timeFormat)
}
4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!