711 字
4 分钟
请求和响应处理
请求处理
绑定 Json 数据
type User struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required,min=6"` Email string `json:"email" binding:"required,email"` Age int `json:"age" binding:"gte=0,lte=130"`}
func main() { r := gin.Default()
r.POST("/user", func(c *gin.Context) { // 绑定 JSON 数据 // 1. 绑定到结构体 var user User if err := c.ShouldBindJSON(&user); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
// 2. 绑定到 map var m map[string]any if err := c.ShouldBindJSON(&m); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
// 3. 绑定到切片(JSON 数组) var users []User if err := c.ShouldBindJSON(&users); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
// 4. 绑定到 map 切片 var maps []map[string]any if err := c.ShouldBindJSON(&maps); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
// 5. 绑定到任意类型(interface{} / any) var data any if err := c.ShouldBindJSON(&data); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
// 6. 绑定到 json.RawMessage(延迟解析) var raw json.RawMessage if err := c.ShouldBindJSON(&raw); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return } })
r.Run(":8080")}绑定 Xml 数据
type Article struct { XMLName xml.Name `xml:"article"` Title string `xml:"title" binding:"required"` Content string `xml:"content" binding:"required"` Author string `xml:"author"`}
func main() { r := gin.Default()
r.POST("/article", func(c *gin.Context) { var article Article
if err := c.ShouldBindXML(&article); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
c.JSON(http.StatusOK, article) })
r.Run(":8080")}绑定查询参数和表单
type SearchQuery struct { Query string `form:"q" binding:"required"` Page int `form:"page" binding:"gte=1"` PageSize int `form:"page_size" binding:"gte=1,lte=100"` Sort string `form:"sort"`}
func main() { r := gin.Default()
r.GET("/search", func(c *gin.Context) { var query SearchQuery
if err := c.ShouldBindQuery(&query); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
c.JSON(http.StatusOK, gin.H{ "query": query.Query, "page": query.Page, "page_size": query.PageSize, "sort": query.Sort, }) })
r.Run(":8080")}绑定 URI 参数
type UserID struct { ID int `uri:"id" binding:"required,gte=1"`}
func main() { r := gin.Default()
r.GET("/user/:id", func(c *gin.Context) { var userID UserID
if err := c.ShouldBindUri(&userID); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return }
c.JSON(http.StatusOK, gin.H{ "user_id": userID.ID, }) })
r.Run(":8080")}响应处理
Json 响应
func main() { r := gin.Default()
// 使用 gin.H r.GET("/json1", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "Hello", "status": 200, }) })
// 使用结构体 r.GET("/json2", func(c *gin.Context) { type Response struct { Message string `json:"message"` Status int `json:"status"` }
c.JSON(http.StatusOK, Response{ Message: "Hello", Status: 200, }) })
// 使用 Map r.GET("/json3", func(c *gin.Context) { data := map[string]interface{}{ "message": "Hello", "status": 200, } c.JSON(http.StatusOK, data) })
// SecureJSON(防止 JSON 劫持) r.GET("/secure-json", func(c *gin.Context) { c.SecureJSON(http.StatusOK, gin.H{ "data": "sensitive data", }) })
// JSONP r.GET("/jsonp", func(c *gin.Context) { c.JSONP(http.StatusOK, gin.H{ "message": "Hello JSONP", }) })
// AsciiJSON(转义非 ASCII 字符) r.GET("/ascii-json", func(c *gin.Context) { c.AsciiJSON(http.StatusOK, gin.H{ "message": "你好,世界", }) })
// PureJSON(不转义 HTML 字符) r.GET("/pure-json", func(c *gin.Context) { c.PureJSON(http.StatusOK, gin.H{ "html": "<b>Hello</b>", }) })
r.Run(":8080")}Xml 响应
func main() { r := gin.Default()
r.GET("/xml", func(c *gin.Context) { type User struct { XMLName xml.Name `xml:"user"` Name string `xml:"name"` Age int `xml:"age"` }
c.XML(http.StatusOK, User{ Name: "John", Age: 30, }) })
r.Run(":8080")}HTML 响应
func main() { r := gin.Default()
// 加载 HTML 模板 r.LoadHTMLGlob("templates/*")
r.GET("/html", func(c *gin.Context) { c.HTML(http.StatusOK, "index.html", gin.H{ "title": "Gin Tutorial", "name": "John", }) })
r.Run(":8080")}模板文件 templates/index.html
<!DOCTYPE html><html><head> <title>{{ .title }}</title></head><body> <h1>Hello, {{ .name }}!</h1></body></html>重定向
func main() { r := gin.Default()
// HTTP 重定向 r.GET("/redirect", func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, "https://www.google.com") })
// 路由重定向 r.GET("/old-path", func(c *gin.Context) { c.Request.URL.Path = "/new-path" r.HandleContext(c) })
r.GET("/new-path", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "New path", }) })
r.Run(":8080")}流式响应
func main() { r := gin.Default()
r.GET("/stream", func(c *gin.Context) { c.Stream(func(w io.Writer) bool { for i := 0; i < 10; i++ { fmt.Fprintf(w, "data: %d\n\n", i) time.Sleep(time.Second) } return false }) })
r.Run(":8080")}分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 89 天
部分内容可能已过时