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} } }