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

Go中json.NewDecoder无请求体报EOF,传{}获默认值的原因

Go中json.Decoder处理空请求体与空JSON对象的行为差异原理

1. 无请求体时返回EOF错误的原因

当HTTP请求不携带任何请求体时,r.Body对应一个空的读取流。json.NewDecoder(r.Body).Decode()尝试读取JSON数据时,会直接遇到EOF(文件结束符)——这属于无效的JSON输入(JSON规范要求至少包含一个有效值,比如对象、数组、字符串等),因此Decode方法会返回io.EOF错误。

此时你的代码会进入错误处理分支,直接返回BadRequest响应,不会执行后续的结构体输出逻辑。但要注意:声明的input结构体变量本身在Go中已经是零值状态,只是因为Decode报错,你没机会输出它。

2. 空JSON对象{}时返回零值的原因

空JSON对象{}是合法的JSON格式,Decoder可以正常解析。解析过程中,因为JSON对象里没有任何键值对,结构体中所有字段都找不到对应的JSON键,所以这些字段会保留Go类型的默认零值(比如string为空串、int32为0、[]string为空切片)。此时Decode方法不会返回错误,代码会执行到输出逻辑,打印出结构体的零值。

实现两种情况都返回零值的处理方案

如果希望无请求体时也返回结构体零值,可以在错误处理中单独捕获io.EOF错误,将其视为合法情况处理:

func (app *application) createMovieHandler(w http.ResponseWriter, r *http.Request) {
    var input struct {
        Title   string   `json:"title"`
        Year    int32    `json:"year"`
        Runtime int32    `json:"runtime"`
        Genres  []string `json:"genres"`
    }

    err := json.NewDecoder(r.Body).Decode(&input)
    if err != nil {
        if err == io.EOF {
            // 无请求体时,直接输出零值结构体
            fmt.Fprintf(w, "%+v\n", input)
            return
        }
        app.errorResponse(w, r, http.StatusBadRequest, err.Error())
        return
    }
    fmt.Fprintf(w, "%+v\n", input)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:55:59