我在 Golang 中使用 Echo Web 框架,并且编写了这段代码
package main
import (
"github.com/labstack/echo/v4"
"net/http"
)
type ProjectPath struct {
ID string `param:"id"`
}
type ProjectBody struct {
Name string `json:"name"`
}
func main() {
e := echo.New()
e.POST("/project/:id", getProjectHandler)
e.Start(":8080")
}
func getProjectHandler(c echo.Context) error {
path := new(ProjectPath)
if err := c.Bind(path); err != nil {
return err
}
body := new(ProjectBody)
if err := c.Bind(body); err != nil {
return err
}
// Access the fields separately
projectID := path.ID
projectName := body.Name
// Do something with the path and body fields...
// Return a response
return c.String(http.StatusOK, "Project ID: "+projectID+", Project Name: "+projectName)
}
我试图在 post 请求中分别绑定路径参数和 json 正文,但在尝试运行它时收到 EOF 错误。
我正在使用replit进行测试,服务器运行在:
https://echotest.sandeepacharya.repl.co
卷曲发布请求:
curl -X POST https://echotest.sandeepacharya.repl.co/project/123 -H "Content-Type: application/json" -d '{"name":"Sandeep"}'
回应:
{"message":"EOF"}
如果您想单独进行绑定,那么您需要使用特定源绑定方法。然而,这些方法在上下文中不可用,而是由
DefaultBinder
. 实现
另请参阅:https://echo.labstack.com/guide/binding/#direct-source
func getProjectHandler(c echo.Context) error {
path := new(ProjectPath)
if err := (&echo.DefaultBinder{}).BindPathParams(c, path); err != nil {
return err
}
body := new(ProjectBody)
if err := (&echo.DefaultBinder{}).BindBody(c, body); err != nil {
return err
}
// Access the fields separately
projectID := path.ID
projectName := body.Name
// Do something with the path and body fields...
// Return a response
return c.String(http.StatusOK, "Project ID: "+projectID+", Project Name: "+projectName)
}
Bind() 直接从套接字读取请求体,一旦读取就无法再次读取,因此出现 EOF 错误
https://github.com/labstack/echo/issues/782#issuecomment-317503513
出现该问题的原因是您尝试两次绑定请求体。第二个
c.Bind()
将引发错误,因为请求正文已被读取和使用。
如果你想读取不同结构的请求,你可以按照这种方法
package main
import (
"fmt"
"net/http"
"github.com/labstack/echo/v4"
)
type ProjectPath struct {
ID string `param:"id"`
}
type ProjectBody struct {
Name string `json:"name"`
}
type ProjectRequest struct {
ProjectPath
ProjectBody
}
func main() {
e := echo.New()
e.POST("/project/:id", getProjectHandler)
e.Start(":8080")
}
func getProjectHandler(c echo.Context) error {
project := new(ProjectRequest)
if err := c.Bind(project); err != nil {
fmt.Println("Error happened due to::", err)
return err
}
// Access the fields separately
projectID := project.ID
projectName := project.Name
// Do something with the path and body fields...
// Return a response
return c.String(http.StatusOK, "Project ID: "+projectID+", Project Name: "+projectName)
}
或者你可以只使用一个结构体来绑定请求
type ProjectRequest struct {
Name string `json:"name"`
ID string `param:"id"`
}