Gin框架返回[]Employee数组为空的问题排查
问题原因与解决方案
你的问题根源在于TypeName结构体的自定义MarshalJSON方法返回了不合法的JSON格式,再加上People嵌套了TypeName,导致整个Employee数组的序列化逻辑被破坏,最终Gin无法生成有效的JSON响应,所以Postman显示为空。
具体问题点
你写的MarshalJSON返回的是[]byte("Joe"),这只是普通字符串,不是合法的JSON值——JSON字符串必须用双引号包裹。而且嵌套结构体序列化时,这个非法返回值会导致整个序列化流程出错,Gin内部处理失败后就返回了空响应。
修复方案
方案1:移除自定义MarshalJSON(推荐,除非你确实需要自定义序列化)
如果不需要对TypeName做特殊序列化,直接删掉这个方法,让Go的默认JSON序列化处理所有字段:
package main import ( "github.com/gin-gonic/gin" "net/http" ) type TypeName struct { Name string `json:"name" binding:"required"` } // 移除这个自定义MarshalJSON方法 // func (p TypeName) MarshalJSON() ([]byte, error) { // return []byte("Joe"), nil // } type People struct { Height int32 `json:"height" binding:"required"` Weight int32 `json:"weight" binding:"required"` TypeName } type Employee struct { Salary int `json:"salary"` People } func main() { r := gin.Default() r.GET("/employees", func(c *gin.Context) { employeeArray := []Employee{ { Salary: 10000, People: People{ Height: 170, Weight: 80, TypeName: TypeName{Name: "Joe1"}, }, }, { Salary: 20000, People: People{ Height: 175, Weight: 80, TypeName: TypeName{Name: "Joe2"}, }, }, } c.JSON(http.StatusOK, employeeArray) }) _ = r.Run() }
方案2:修复自定义MarshalJSON的返回格式
如果确实需要自定义TypeName的序列化,要返回合法的JSON值。比如你想把Name固定为"Joe",应该返回带双引号的字符串:
func (p TypeName) MarshalJSON() ([]byte, error) { // 返回合法的JSON字符串(带双引号) return []byte(`"Joe"`), nil }
或者如果要序列化TypeName的结构体字段,用标准方式避免递归调用:
import "encoding/json" func (p TypeName) MarshalJSON() ([]byte, error) { // 用别名避免递归调用MarshalJSON type alias TypeName return json.Marshal(alias{Name: "Joe"}) }
验证效果
修复后,Postman会收到正常的JSON响应,比如方案1的响应示例:
[ { "salary": 10000, "height": 170, "weight": 80, "name": "Joe1" }, { "salary": 20000, "height": 175, "weight": 80, "name": "Joe2" } ]
内容的提问来源于stack exchange,提问作者Vladimir Chizh
相关产品推荐
相关产品推荐

