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
相关产品推荐
相关产品推荐

