求助,关于json反序列化问题

DG9Jww · 2022-08-05 23:00:58 · 3149 次点击 · 预计阅读时间 1 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2022-08-05 23:00:58 的文章,其中的信息可能已经有所发展或是发生改变。

现状如下:

我现在有很多API,每个API的数据都不一样,每个接口我所需要的数据也不一样,所以我针对每一个接口,都写了不同的结构体。现在我获得响应,需要根据不同的API初始化不同的结构体,再把获取的json数据反序列化到这个结构体

问题如下:

由于存在很多API,也就是说很多不同结构体,我在json.Unmarshal()的时候,必须传interface,但是使用Unmarshal()函数的时候,如果传参是interface,那么一定会反序列化成map格式,这样导致我使用结构体过滤的数据无效。

例子:

type API struct {
    MyTarget    string    `json:"target"`
}

type API2 struct {
    MyTarget2    string    `json:"target2"`
}

type API3 struct {
    MyTarget3    string    `json:"target3"`
}

var APISlice = map[string]interface{}{
    "api":API{},
    "api2":API2{},
    "api3":API3{},
}

func main() {
    data = []byte{}
    str := "api1"    //假设是api1,实际业务我是遍历每一个api的
    myStruct := APISlice[str]
    json.Unmarshal(data,&myStruct)    //此时得到的结果,是一个map,并且响应的结果(即data)全部装进这个map里面了
                                //而我想要的是我已经用结构体定义好的字段,target就是我想要得
}

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3149 次点击  ∙  1 赞  
加入收藏 微博
4 回复  |  直到 2022-08-18 10:23:06
jan-bar
jan-bar · #1 · 3年之前

json.RawMessage解君愁

sanrentai
sanrentai · #2 · 3年之前

示例代码没看懂你说的是什么问题, data是一个空数组,Unmarshal 以后肯定是nil 啊

guokun1998
guokun1998 · #3 · 3年之前

type struct1 struct {
    Name string
}

type struct2 struct {
    Name string
}

type temp1 struct {
    V1 *struct1
    V2 *struct2
}

type temp2 struct {
    Data json.RawMessage
}

// test1 使用指针预定义所有结构体,当没有该数据时,该指针域为nil
func test1(data []byte, name string)  {
    temp := temp1{}
    err := json.Unmarshal(data, &temp)
    if err != nil {
        return 
    }
    if name == "v1" {
        println(temp.V1.Name)
    }
}

// test2 使用 json.RawMessage 接受,再进行区分解析
func test2(data []byte, name string) {
    temp := temp2{}
    err := json.Unmarshal(data, &temp)
    if err != nil {
        return
    }
    if name == "v1" {
        s1 := struct1{}
        err := json.Unmarshal(temp.data, &s1)
        if err != nil {
            return
        }
        println(s1.Name)
    }
}
zhanghuizong
zhanghuizong · #4 · 3年之前

如果你用了go1.18版本. 用泛型尝试效果也不错

type API struct {
    MyTarget string `json:"target"`
}

type API2 struct {
    MyTarget2 string `json:"target2"`
}

type API3 struct {
    MyTarget3 string `json:"target3"`
}

type ApiType interface {
    API | API2 | API3
}

func decode[T ApiType](s string, t *T) {
    err := json.Unmarshal([]byte(s), t)
    if err != nil {
        fmt.Println("解析异常")
    }
}

func main() {
    s1 := "{\"target\":\"target\"}"
    api1 := new(API)
    decode(s1, api1)
    fmt.Println(api1.MyTarget)

    s2 := "{\"target2\":\"target2\"}"
    api2 := new(API2)
    decode(s2, api2)
    fmt.Println(api2.MyTarget2)

    s3 := "{\"target3\":\"target3\"}"
    api3 := new(API3)
    decode(s3, api3)
    fmt.Println(api3.MyTarget3)
}
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传