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

