Go 中時間型別欄位的 JSON 序列化和反序列化的處理技巧

夜幕下的風之發表於2020-05-20

我主要從其他博主教程那裡學來的技巧: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 協議》,轉載必須註明作者和本文連結

相關文章