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

Golang Gofiber:如何用BodyParser接收非结构化JSON数组请求

解决Gofiber BodyParser解析含location数组请求体的问题

错误原因分析

你遇到的json: cannot unmarshal object into Go value of type []apisLocation.Locations错误,核心是请求体最外层是JSON对象而非数组。比如实际请求体结构大概率是这样:

{
  "location": [
    {"lat": 39.9042, "lng": 116.4074},
    {"lat": 31.2304, "lng": 121.4737}
  ]
}

而你直接用[]Locations类型解析,相当于告诉Go要解析一个数组,但实际传入的是包含数组字段的对象,自然解析失败。


解决方案

1. 明确结构体解析(推荐,适合已知请求结构的场景)

定义匹配请求体结构的结构体,直接解析到该类型:

// 定义Location结构体,根据实际字段调整
type Location struct {
    Lat float64 `json:"lat"`
    Lng float64 `json:"lng"`
    // 其他字段按需添加
}

// 定义外层请求体结构体
type LocationRequest struct {
    Location []Location `json:"location"` // JSON标签要和请求体中的字段名严格一致
}

// 在Gofiber路由处理函数中使用
func handleLocationRequest(c *fiber.Ctx) error {
    var req LocationRequest
    if err := c.BodyParser(&req); err != nil {
        return c.Status(fiber.StatusBadRequest).SendString("解析请求体失败: " + err.Error())
    }

    // 处理解析后的位置数组
    fmt.Println("收到的位置数据:", req.Location)
    return c.JSON(fiber.Map{"status": "success", "data": req.Location})
}

2. 非结构化解析(适合不确定请求结构的场景)

如果请求体结构不固定,可以用map[string]interface{}或json.RawMessage接收:

方式一:用map[string]interface{}接收
func handleUnstructuredRequest(c *fiber.Ctx) error {
    var data map[string]interface{}
    if err := c.BodyParser(&data); err != nil {
        return c.Status(fiber.StatusBadRequest).SendString("解析请求体失败: " + err.Error())
    }

    // 提取location数组
    locationsRaw, ok := data["location"].([]interface{})
    if !ok {
        return c.Status(fiber.StatusBadRequest).SendString("请求体中location字段不是数组")
    }

    // 按需转换为具体类型
    var locations []Location
    for _, locRaw := range locationsRaw {
        locMap, ok := locRaw.(map[string]interface{})
        if !ok {
            continue
        }
        loc := Location{
            Lat: locMap["lat"].(float64),
            Lng: locMap["lng"].(float64),
        }
        locations = append(locations, loc)
    }

    return c.JSON(fiber.Map{"status": "success", "data": locations})
}
方式二:用json.RawMessage保留原始JSON再按需解析
import "encoding/json"

func handleRawRequest(c *fiber.Ctx) error {
    var rawData map[string]json.RawMessage
    if err := c.BodyParser(&rawData); err != nil {
        return c.Status(fiber.StatusBadRequest).SendString("解析请求体失败: " + err.Error())
    }

    // 单独解析location字段为数组
    var locations []Location
    if err := json.Unmarshal(rawData["location"], &locations); err != nil {
        return c.Status(fiber.StatusBadRequest).SendString("解析location数组失败: " + err.Error())
    }

    return c.JSON(fiber.Map{"status": "success", "data": locations})
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:50:24