Context上下文 #
一、Context概述 #
Context是Echo框架的核心对象,封装了HTTP请求和响应的所有信息。
1.1 Context结构 #
go
type Context interface {
Request() *http.Request
Response() *http.Response
...
}
1.2 Context作用 #
text
┌─────────────────────────────────────────────────────────┐
│ Context作用 │
├─────────────────────────────────────────────────────────┤
│ │
│ 请求信息 │
│ ├── 获取请求参数 │
│ ├── 获取请求头 │
│ ├── 获取请求体 │
│ └── 获取Cookie │
│ │
│ 响应操作 │
│ ├── 设置响应内容 │
│ ├── 设置响应头 │
│ ├── 设置Cookie │
│ └── 设置状态码 │
│ │
│ 数据传递 │
│ ├── 中间件间传递数据 │
│ └── 存储请求相关数据 │
│ │
└─────────────────────────────────────────────────────────┘
二、请求信息 #
2.1 获取Request对象 #
go
e.GET("/", func(c echo.Context) error {
req := c.Request()
method := req.Method
url := req.URL.String()
host := req.Host
proto := req.Proto
return c.JSON(http.StatusOK, map[string]string{
"method": method,
"url": url,
"host": host,
"proto": proto,
})
})
2.2 获取请求头 #
go
e.GET("/headers", func(c echo.Context) error {
auth := c.Request().Header.Get("Authorization")
contentType := c.Request().Header.Get("Content-Type")
userAgent := c.Request().UserAgent()
return c.JSON(http.StatusOK, map[string]string{
"authorization": auth,
"content-type": contentType,
"user-agent": userAgent,
})
})
2.3 获取客户端信息 #
go
e.GET("/client", func(c echo.Context) error {
realIP := c.RealIP()
remoteAddr := c.Request().RemoteAddr
scheme := c.Scheme()
isTLS := c.IsTLS()
return c.JSON(http.StatusOK, map[string]interface{}{
"realIP": realIP,
"remoteAddr": remoteAddr,
"scheme": scheme,
"isTLS": isTLS,
})
})
2.4 获取路径信息 #
go
e.GET("/path/*", func(c echo.Context) error {
path := c.Path()
param := c.Param("*")
return c.JSON(http.StatusOK, map[string]string{
"path": path,
"param": param,
})
})
三、响应操作 #
3.1 获取Response对象 #
go
e.GET("/", func(c echo.Context) error {
res := c.Response()
res.Header().Set("X-Custom", "value")
res.WriteHeader(http.StatusOK)
return nil
})
3.2 设置响应头 #
go
e.GET("/headers", func(c echo.Context) error {
c.Response().Header().Set("X-Request-ID", "12345")
c.Response().Header().Add("X-Custom", "value1")
c.Response().Header().Add("X-Custom", "value2")
return c.String(http.StatusOK, "OK")
})
3.3 设置状态码 #
go
e.GET("/status", func(c echo.Context) error {
return c.String(http.StatusCreated, "Created")
})
四、参数获取 #
4.1 路径参数 #
go
e.GET("/users/:id", func(c echo.Context) error {
id := c.Param("id")
return c.String(http.StatusOK, "User ID: "+id)
})
4.2 查询参数 #
go
e.GET("/search", func(c echo.Context) error {
q := c.QueryParam("q")
page := c.QueryParam("page")
return c.JSON(http.StatusOK, map[string]string{
"q": q,
"page": page,
})
})
4.3 表单参数 #
go
e.POST("/login", func(c echo.Context) error {
username := c.FormValue("username")
password := c.FormValue("password")
return c.JSON(http.StatusOK, map[string]string{
"username": username,
})
})
4.4 绑定参数 #
go
type User struct {
Name string `json:"name" form:"name" query:"name"`
Email string `json:"email" form:"email" query:"email"`
}
e.POST("/users", func(c echo.Context) error {
u := new(User)
if err := c.Bind(u); err != nil {
return err
}
return c.JSON(http.StatusCreated, u)
})
五、Cookie操作 #
5.1 获取Cookie #
go
e.GET("/cookie", func(c echo.Context) error {
cookie, err := c.Cookie("session")
if err != nil {
return c.String(http.StatusOK, "No cookie")
}
return c.String(http.StatusOK, "Session: "+cookie.Value)
})
5.2 设置Cookie #
go
e.GET("/set-cookie", func(c echo.Context) error {
cookie := &http.Cookie{
Name: "session",
Value: "abc123",
Path: "/",
HttpOnly: true,
Secure: true,
MaxAge: 3600,
}
c.SetCookie(cookie)
return c.String(http.StatusOK, "Cookie set")
})
5.3 删除Cookie #
go
e.GET("/delete-cookie", func(c echo.Context) error {
cookie := &http.Cookie{
Name: "session",
Value: "",
Path: "/",
MaxAge: -1,
}
c.SetCookie(cookie)
return c.String(http.StatusOK, "Cookie deleted")
})
5.4 获取所有Cookie #
go
e.GET("/cookies", func(c echo.Context) error {
cookies := c.Cookies()
result := make(map[string]string)
for _, cookie := range cookies {
result[cookie.Name] = cookie.Value
}
return c.JSON(http.StatusOK, result)
})
六、数据存储 #
6.1 Set/Get #
go
func authMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
user := &User{ID: 1, Name: "张三"}
c.Set("user", user)
return next(c)
}
}
e.GET("/profile", func(c echo.Context) error {
user := c.Get("user").(*User)
return c.JSON(http.StatusOK, user)
})
6.2 类型安全获取 #
go
func getUser(c echo.Context) *User {
if user, ok := c.Get("user").(*User); ok {
return user
}
return nil
}
6.3 存储多个值 #
go
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
c.Set("requestID", uuid.New().String())
c.Set("startTime", time.Now())
c.Set("userID", "123")
return next(c)
}
})
七、响应方法 #
7.1 String响应 #
go
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
7.2 JSON响应 #
go
e.GET("/json", func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]string{
"message": "Hello",
})
})
7.3 JSONP响应 #
go
e.GET("/jsonp", func(c echo.Context) error {
callback := c.QueryParam("callback")
return c.JSONP(http.StatusOK, callback, map[string]string{
"message": "Hello",
})
})
7.4 XML响应 #
go
e.GET("/xml", func(c echo.Context) error {
return c.XML(http.StatusOK, map[string]string{
"message": "Hello",
})
})
7.5 HTML响应 #
go
e.GET("/html", func(c echo.Context) error {
return c.HTML(http.StatusOK, "<h1>Hello, World!</h1>")
})
7.6 文件响应 #
go
e.GET("/file", func(c echo.Context) error {
return c.File("static/hello.txt")
})
7.7 附件下载 #
go
e.GET("/download", func(c echo.Context) error {
return c.Attachment("files/report.pdf", "report.pdf")
})
7.8 内联文件 #
go
e.GET("/inline", func(c echo.Context) error {
return c.Inline("files/document.pdf", "document.pdf")
})
7.9 Blob响应 #
go
e.GET("/blob", func(c echo.Context) error {
data := []byte("Hello, World!")
return c.Blob(http.StatusOK, "text/plain", data)
})
7.10 Stream响应 #
go
e.GET("/stream", func(c echo.Context) error {
reader := strings.NewReader("Hello, World!")
return c.Stream(http.StatusOK, "text/plain", reader)
})
7.11 重定向 #
go
e.GET("/redirect", func(c echo.Context) error {
return c.Redirect(http.StatusFound, "/new-path")
})
7.12 无内容 #
go
e.DELETE("/users/:id", func(c echo.Context) error {
return c.NoContent(http.StatusNoContent)
})
八、路径和路由 #
8.1 获取路径 #
go
e.GET("/api/users/:id", func(c echo.Context) error {
path := c.Path()
return c.String(http.StatusOK, "Path: "+path)
})
输出:
text
Path: /api/users/:id
8.2 路由名称 #
go
e.GET("/users/:id", func(c echo.Context) error {
return c.String(http.StatusOK, "User")
}).Name = "user.get"
e.GET("/url", func(c echo.Context) error {
url := c.Echo().Reverse("user.get", "123")
return c.String(http.StatusOK, "URL: "+url)
})
输出:
text
URL: /users/123
九、Context扩展 #
9.1 自定义Context #
go
type CustomContext struct {
echo.Context
}
func (cc *CustomContext) Foo() string {
return "foo"
}
func (cc *CustomContext) Bar() string {
return "bar"
}
func main() {
e := echo.New()
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
cc := &CustomContext{c}
return next(cc)
}
})
e.GET("/", func(c echo.Context) error {
cc := c.(*CustomContext)
return c.String(http.StatusOK, cc.Foo())
})
e.Start(":8080")
}
9.2 Context方法扩展 #
go
func (cc *CustomContext) GetUserID() string {
if userID, ok := cc.Get("userID").(string); ok {
return userID
}
return ""
}
func (cc *CustomContext) IsAuthenticated() bool {
return cc.Get("user") != nil
}
十、完整示例 #
go
package main
import (
"net/http"
"time"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
func main() {
e := echo.New()
e.Use(contextMiddleware)
e.GET("/", home)
e.GET("/info", info)
e.GET("/cookies", handleCookies)
e.POST("/users", createUser)
e.Logger.Fatal(e.Start(":8080"))
}
func contextMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
c.Set("requestID", uuid.New().String())
c.Set("startTime", time.Now())
return next(c)
}
}
func home(c echo.Context) error {
requestID := c.Get("requestID").(string)
c.Response().Header().Set("X-Request-ID", requestID)
return c.JSON(http.StatusOK, map[string]string{
"message": "Welcome",
"requestID": requestID,
})
}
func info(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]interface{}{
"method": c.Request().Method,
"path": c.Path(),
"realIP": c.RealIP(),
"scheme": c.Scheme(),
"isTLS": c.IsTLS(),
"requestID": c.Get("requestID"),
})
}
func handleCookies(c echo.Context) error {
if c.Request().Method == http.MethodGet {
cookie, err := c.Cookie("visit")
if err != nil {
cookie = &http.Cookie{
Name: "visit",
Value: "1",
Expires: time.Now().Add(24 * time.Hour),
}
c.SetCookie(cookie)
return c.String(http.StatusOK, "First visit")
}
return c.String(http.StatusOK, "Visit count: "+cookie.Value)
}
return c.NoContent(http.StatusMethodNotAllowed)
}
func createUser(c echo.Context) error {
u := new(User)
if err := c.Bind(u); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
u.ID = 1
return c.JSON(http.StatusCreated, u)
}
十一、总结 #
Context方法要点:
| 方法 | 用途 |
|---|---|
Request() |
获取请求对象 |
Response() |
获取响应对象 |
Param() |
获取路径参数 |
QueryParam() |
获取查询参数 |
FormValue() |
获取表单参数 |
Bind() |
绑定数据 |
Cookie() |
获取Cookie |
SetCookie() |
设置Cookie |
Set() |
存储数据 |
Get() |
获取数据 |
JSON() |
JSON响应 |
String() |
字符串响应 |
HTML() |
HTML响应 |
准备好学习请求处理了吗?让我们进入下一章!
最后更新:2026-03-28