You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go解析含type字段的JSON数组为结构体的问题及解决

解决Go Fiber中JSON数组解析报错:无法将数组反序列化为单个结构体类型

问题场景

处理POST请求时,请求体始终是包含type字段的JSON数组(示例如下),但解析时触发错误:

error =  json: cannot unmarshal array into Go value of type main.Entry

无法修改请求体格式,目标是将其解析为结构体数组,循环处理后存入InfluxDB。

示例请求体:

[{"type":"sgv","device":"0EM48R5JQ","dateString":"2023-06-23T22:39:16.000+02:00","date":1687552756000,"sgv":127,"delta":-0.400,"direction":"Flat","noise":1,"filtered":127000,"unfiltered":127000,"rssi":100}]

原代码(存在问题)

package main

import (
       "fmt"
       "github.com/gofiber/fiber/v2"
       "github.com/gofiber/fiber/v2/middleware/logger"
       "github.com/gofiber/fiber/v2/middleware/compress"
       )

func main() {
    app := fiber.New()

    app.Use(logger.New(logger.Config{
    Format: "[${ip}]:${port} ${status} - ${method} ${path} - ${reqHeaders}\n${body}\n",
    }))

    app.Use(compress.New(compress.Config{
    Level: compress.LevelBestSpeed, // 1
    }))


type Entry struct {
    Type string `json:"type"`
    Device string `json:"device"`
    DateString string `json:"dateString"`
    Date string `json:"date"`
    Sgv string `json:"sgv"`
    Delta string `json:"delta"`
    Direction string `json:"direction"`
    Noise string `json:"noise"`
    Filtered string `json:"filtered"`
    Unfiltered string `json:"unfiltered"`
    Rssi string `json:"rssi"`
}


type Entries struct {
    Entries []Entry
    }


    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World!")
    })

    app.Post("/api/v1/entries", func(c *fiber.Ctx) error {
    entry := new(Entry)

    if err := c.BodyParser(entry); err != nil {
        fmt.Println("error = ",err)
        return c.SendStatus(500)
    }

    return c.SendStatus(200)
    })

    app.Post("/entries", func(c *fiber.Ctx) error {
    return c.SendString("OK")
    })

    app.Post("/devicestatus", func(c *fiber.Ctx) error {
    return c.SendString("OK")
    })

    app.Post("/treatments", func(c *fiber.Ctx) error {
    return c.SendString("OK")
    })

    app.Listen(":3001")
}

错误原因

  1. 解析目标类型不匹配:用单个Entry结构体解析JSON数组,而JSON数组只能反序列化为切片/数组类型,导致类型不兼容报错。
  2. 字段类型不匹配:Entry结构体中多个字段定义为string,但JSON对应值是数字(如date是时间戳整数、sgv是整数、delta是浮点数),会引发隐性解析错误。

修正后代码

package main

import (
    "fmt"
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/fiber/v2/middleware/compress"
    "github.com/gofiber/fiber/v2/middleware/logger"
)

func main() {
    app := fiber.New()

    app.Use(logger.New(logger.Config{
        Format: "[${ip}]:${port} ${status} - ${method} ${path} - ${reqHeaders}\n${body}\n",
    }))

    app.Use(compress.New(compress.Config{
        Level: compress.LevelBestSpeed, // 1
    }))

    type Entry struct {
        Type       string  `json:"type"`
        Device     string  `json:"device"`
        DateString string  `json:"dateString"`
        Date       int64   `json:"date"` // 修正为int64匹配时间戳数字
        Sgv        int     `json:"sgv"` // 修正为int匹配整数
        Delta      float64 `json:"delta"` // 修正为float64匹配浮点数
        Direction  string  `json:"direction"`
        Noise      int     `json:"noise"` // 修正为int匹配整数
        Filtered   int     `json:"filtered"` // 修正为int匹配整数
        Unfiltered int     `json:"unfiltered"` // 修正为int匹配整数
        Rssi       int     `json:"rssi"` // 修正为int匹配整数
    }

    type Entries []Entry // 直接定义为Entry切片类型

    app.Post("/api/v1/entries", func(c *fiber.Ctx) error {
        entries := new(Entries) // 创建切片指针用于解析数组
        if err := c.BodyParser(entries); err != nil {
            fmt.Println("error:", err)
            return c.SendStatus(fiber.StatusInternalServerError)
        }

        // 循环处理每个条目,可在此添加存入InfluxDB的逻辑
        for _, entry := range *entries {
            fmt.Println(entry)
        }

        return c.SendStatus(fiber.StatusOK)
    })

    app.Listen(":3001")
}

关键修改点

  • 将Entries定义为[]Entry切片类型,而非包含切片的结构体,匹配JSON数组格式。
  • 使用new(Entries)作为BodyParser的目标,实现数组解析。
  • 修正Entry结构体字段类型,完全匹配JSON中的数据类型,避免解析隐性错误。
  • 新增循环遍历逻辑,可直接处理每个条目并写入InfluxDB。

内容的提问来源于stack exchange,提问作者JRSmile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 10:20:41