问题

javascript中能安全表示的数字范围在
而后端用的是int64int64的范围是:
然后就会出现如此神器的现象

解决方法

字符串大法好
在结构体可能出现问题的字段加上json的tag,

type D struct {
    ID   int64  `json:"id,string"`
    Name string 
}

这样就会在序列化的时候自动由int64转为string,反序列化的时候自动由string转为int64
(或者说,一个较为麻烦的方法:自己定义一个Marshal, UnMarshal自己实现int64string互转的过程)
demo如下:

type D struct {
    ID   int64  `json:"id,string"`
    Name string `json:"name"`
}

func main() {
    d := &D{
        ID:   math.MaxInt64,
        Name: "xiaos",
    }
    // json 序列化
    p, err := json.Marshal(d)
    if err != nil {
        return
    }
    fmt.Println(string(p))

    // 反序列化json
    s := `{"ID":"9223372036854775807","Name":"xiaos"}`
    var d2 D
    if err := json.Unmarshal([]byte(s), &d2); err != nil {
        fmt.Println(err)
    }
    fmt.Println(d2)
}

奇技淫巧

忽略字段

在tag中添加-

// 使用tag指定json序列化与反序列化时的行为
type Person struct {
    Name   string `json:"name"` // 指定json序列化/反序列化时使用小写name
    Age    int64
    Gender string `json:"-"` // 指定json序列化/反序列化时忽略此字段
}

忽略空值字段

在对应字段添加omitempty tag来忽略空值字段

// 在tag中添加omitempty忽略空值
// 注意这里 hobby,omitempty 合起来是json tag值,中间用英文逗号分隔
type User struct {
    Name  string   `json:"name"`
    Email string   `json:"email,omitempty"`
    Address []string `json:"address,omitempty"`
}

处理不确定层级的json

如果json串没有固定层级或格式,不好解析,可以使用json.RawMessage原始字节数据保存下来。

type sendMsg struct {
    User string `json:"user"`
    Msg  string `json:"msg"`
}

func rawMessageDemo() {
    //jsonStr := `{"data":{"user":"xs","msg":"一点一点往上爬"},"print":"Hello"}`
    jsonStr := `{"data":{"user":"xs","msg":"一点一点往上爬"},"print":"Hello"}`
    // 定义一个map,value类型为json.RawMessage,方便后续灵活地处理
    var data map[string]json.RawMessage
    if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
        fmt.Printf("json.Unmarshal jsonStr failed, err:%v\n", err)
        return
    }
    var msg sendMsg
    if err := json.Unmarshal(data["data"], &msg); err != nil {
        fmt.Printf("json.Unmarshal failed, err:%v\n", err)
        return
    }
    fmt.Printf("msg:%#v\n", msg)
    // msg:main.sendMsg{User:"xs", Msg:"一点一点往上爬"}
}
func main() {
    rawMessageDemo()
}
分类: go

0 条评论

发表评论

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注

ICP备案号: 辽ICP备20003309号