必须显式调用 ctx.ReadJSON(&v) 解析 JSON 请求体,Iris 不自动绑定;需检查 Content-Type、字段导出并带 json tag;重复调用会 panic;校验需手动配置 app.Validator。

必须显式调用 ctx.ReadJSON(),别指望自动绑定
Iris 不会在 handler 入口自动解析请求体,ctx.ReadJSON(&v) 是唯一可靠入口。用 ctx.FormValue("field") 或 ctx.URLParam("id") 读 JSON 字段一定为空——前者只处理 application/x-www-form-urlencoded,后者只读 query string。
常见错误是看到结构体定义就以为能自动注入,其实 Iris 的结构体参数自动绑定(如 func(ctx iris.Context, req CreateUserReq))仅在 MVC controller 中生效,普通 handler 和中间件里完全不触发。
- 先确认
Content-Type: application/json:用ctx.Request().Header.Get("Content-Type")检查,否则ReadJSON可能静默失败或返回io.EOF - 结构体字段必须导出(首字母大写),且带
json:"name"tag,否则反序列化后字段始终为空 - 重复调用
ReadJSON会 panic:http: read on closed response body,因为Request.Body是单次读取流
ReadJSON 前必须配置 app.Validator
如果你用了 validate:"required,email" 这类 tag,但没给 app.Validator 赋值,校验规则完全不会执行——ReadJSON 成功返回,空字符串、非法邮箱照单全收。
Iris 默认不集成校验器,得自己初始化一个(比如 go-playground/validator/v10),再挂到 app 上:
import "github.com/go-playground/validator/v10"
// ...
app.Validator = iris.Validator{
Func: validator.New().Validate,
}
- 没设
app.Validator→validatetag 彻底失效,和没写一样 -
binding:"email"和validate:"email"效果不同:binding是 Iris 内置简易规则(v12+ 已弃用),validate才走你配的第三方校验器 - 自定义规则(如手机号、密码强度)必须在
app.Run前注册到iris.Validator.Func对应的实例中
路径参数、查询参数、JSON 参数三者完全隔离
别试图用同一个结构体混绑三种参数。Iris 明确区分来源:ctx.Params() 读路径参数(如 /user/{id}),ctx.URLParam() 读 query string(如 ?page=1),ctx.ReadJSON() 读请求体——它们互不影响,也互不转换。
- 路径参数必须用
ctx.Params().Get("id"),写成ctx.URLParam("id")永远返回空 - 查询参数若要转整数,用
ctx.URLParamInt("page")或ctx.URLParamIntDefault("page", 1),别手动strconv.Atoi忘判错 - JSON 请求体里的
{"id": 123}和路径里的/user/123是两回事,业务上需自行决定是否做一致性校验(比如删用户时检查 URL id 和 body id 是否一致)
中间件里解析 JSON 要特别小心 Body 复用
如果中间件需要读 JSON(比如鉴权、日志),必须只读一次,并把结果存进 ctx.Values().Set("parsed_body", &v),handler 里直接取,别再调 ReadJSON。
漏掉这步,handler 里二次调用就会 panic;而如果中间件读完不阻断,又可能让未鉴权请求继续执行业务逻辑。
- 中间件解析后,务必调
ctx.StopExecution()阻断后续流程(比如鉴权失败时) - 想透传原始 body 给 handler?不行。
Request.Body无法重放,只能靠ctx.Values()中转结构体指针 - 不要用
ioutil.ReadAll或io.ReadAll手动读 body——它消耗流且不兼容 Iris 的内部缓冲机制
ReadJSON 成功但字段仍是零值,或者 validate tag 看似写了却没生效——八成是漏了 app.Validator 配置,或者结构体字段没导出、没加 json tag。


















