Golang 序列化与反序列化,包含字段首字母小写和字段时间格式化

 

golang 结构体 json 的时间  序列化与反序列化  格式化解决方案 
// 最近开发项目时候发现一个结构体的 Json 转换的时间格式问题。
// 即这种 1993-01-01T20:08:23.000000028+08:00 这种表示 UTC 方法。
// 从我们习惯来说,更喜欢希望的是 1993-01-01 20:08:23 这种格式
如何处理:

通过 time.Time 类型别名

import (
    "fmt"
    "time"
)

type JsonTime time.Time
// 最近开发项目时候发现一个结构体的 Json 转换的时间格式问题。 
// 即这种 1993-01-01T20:08:23.000000028+08:00 这种表示 UTC 方法。
// 从我们习惯来说,更喜欢希望的是 1993-01-01 20:08:23 这种格式
// 实现它的json序列化方法
func (jsonTime *JsonTime) MarshalJSON() ([]byte, error) {
    var stamp = fmt.Sprintf("\"%s\"", time.Time(*jsonTime).Format("2006-01-02 15:04:05"))
    return []byte(stamp), nil
}

// golang默认time.Time 类型默认解析的日期格式是 RFC3339 标准,
// 也就是 2006-01-02T15:04:05Z07:00 的格式,所以前端传入的json字符串中时间格
// 式为 yyyy-MM-dd HH:mm:ss时候,解析为time.Time格式会报错
// 解决方案:利用time.Time别名类型实现UnmarshalJSON 方法,既可以解析成功

// 实现它的json反序列化方法
// 自定义json反序列化  golang 结构体 json 的时间格式化解决方案
func (jsonTime *JsonTime) UnmarshalJSON(data []byte) error {
    t, err := time.Parse(`"2006-01-02 15:04:05"`, string(data))
    if err != nil {
        return err
    }
    *jsonTime = JsonTime(t)
    return nil
}

定义Struct   若字段是时间类型的 就设置成 JsonTime类型

// json的作用用于标记 序列化时的输出
type Student struct {
    Id          int      `json:"id"`    // 这里的json表示序列化时小写
    Name        string   `json:"name"`
    HomeAddress string   `json:"homeAddress"`
    CreateTime  JsonTime `json:"createTime"`   // ****** 注意序列化与反序列化关键在于类型JsonTime
}

实现序列化与反序列化

package main

import (
    "encoding/json"
    "fmt"
    "go_code/mytwo/bbb"
    "runtime/debug"
    "sort"
    "strconv"
    "strings"
    "time"
)

func main() {
    // struct 序列化与反序列化
    var student = Student{1, "张三", "江西", JsonTime(time.Date(2024, 5, 25, 20, 8, 23, 28, time.Local))}
    jsonByte, err := json.Marshal(&student)   // 通过encoding/json包里的Marshal序列化
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("结果:", string(jsonByte))
    }
    jsonStr := string(jsonByte)
    student2 := new(Student)
    err = json.Unmarshal([]byte(jsonStr), &student2)// 通过encoding/json包里的Unmarshal反序列化
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(student2, "时间", time.Time(student2.CreateTime))
    }

}

还可以通过Gob对Struct 进行序列化与反序列化

标准库gob是golang提供的“私有”的编解码方式,它的效率会比json,xml等更高,特别适合在Go语言程序间传递数据

序列化

package main
 
import (
 "bytes"
 "encoding/gob"
 "fmt"
)
 
type Girl struct {
 Name    string
 Age    int  `json:"age"`
 Gender   string `json:"gender"`
 Where   string `json:"where"`
 Is_married bool  `json:"is_married"`
}
 
func main() {
 g := Girl{"satori", 16, "f", "东方地灵殿", false}
 
 //创建缓存
 buf := new(bytes.Buffer)
 //把指针丢进去
 enc := gob.NewEncoder(buf)
 
 //调用Encode进行序列化
 if err := enc.Encode(g); err != nil {
 fmt.Println(err)
 return
 } else {
 //序列化的内容会被放进buf里面
 fmt.Println(buf.String())
 /*
 G��Girl�� Name Age Gender Where 
 Is_married  !��satori f东方地灵殿
 */
 }
}

发现是乱码,因为这类似python的pickle,是该语言独有的。所以我们不认识没关系,golang认识就行了

反序列化

package main
 
import (
 "bytes"
 "encoding/gob"
 "fmt"
)
 
type Girl struct {
 Name    string
 Age    int  `json:"age"`
 Gender   string `json:"gender"`
 Where   string `json:"where"`
 Is_married bool  `json:"is_married"`
}
 
func main() {
 g := Girl{"satori", 16, "f", "东方地灵殿", false}
 
 buf := new(bytes.Buffer)
 enc := gob.NewEncoder(buf)
 if err := enc.Encode(g);err != nil {
 fmt.Println(err)
 return
 }
 
 var g1 = Girl{}
 //bytes.NewBuffer和bytes.Buffer类似,只不过可以传入一个初始的byte数组,返回一个指针
 dec := gob.NewDecoder(bytes.NewBuffer(buf.Bytes()))
 //调用Decode方法,传入结构体对象指针,会自动将buf.Bytes()里面的内容转换成结构体
 if err := dec.Decode(&g1);err != nil {
 fmt.Println(err)
 return
 } else {
 fmt.Println(g1) // {satori 16 f 东方地灵殿 false}
 }
}

 

 

posted @ 2024-05-25 18:35  酒沉吟  阅读(146)  评论(0编辑  收藏  举报