表单绑定可以处理
application/x-www-form-urlencoded和multipart/form-data格式的数据。
type LoginForm struct {
Username string `form:"username" binding:"required"`
Password string `form:"password" binding:"required"`
}
r.POST("/login", func(c *gin.Context) {
var form LoginForm
if err := c.ShouldBind(&form); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{
"username": form.Username,
"message": "登录成功",
})
})
请求:
curl -X POST http://localhost:8080/login \
-d "username=alice&password=secret"
type User struct {
Name string `form:"name"`
Email string `form:"email"`
Age int `form:"age"`
Active bool `form:"active"`
}
type UploadForm struct {
Name string `form:"name"`
File *multipart.FileHeader `form:"file" binding:"required"`
}
r.POST("/upload", func(c *gin.Context) {
var form UploadForm
if err := c.ShouldBind(&form); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
dst := "./uploads/" + form.File.Filename
c.SaveUploadedFile(form.File, dst)
c.JSON(200, gin.H{
"name": form.Name,
"filename": form.File.Filename,
"size": form.File.Size,
})
})
type MultiUploadForm struct {
Name string `form:"name"`
Files []*multipart.FileHeader `form:"files" binding:"required"`
}
r.POST("/upload", func(c *gin.Context) {
var form MultiUploadForm
if err := c.ShouldBind(&form); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
for _, file := range form.Files {
dst := "./uploads/" + file.Filename
c.SaveUploadedFile(file, dst)
}
c.JSON(200, gin.H{
"name": form.Name,
"count": len(form.Files),
})
})
type FilterForm struct {
Tags []string `form:"tags"`
}
r.POST("/filter", func(c *gin.Context) {
var form FilterForm
if err := c.ShouldBind(&form); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"tags": form.Tags})
})
请求:
curl -X POST http://localhost:8080/filter \
-d "tags=go&tags=web&tags=api"
package main
import (
"github.com/gin-gonic/gin"
"mime/multipart"
"net/http"
)
type LoginForm struct {
Username string `form:"username" binding:"required,min=3"`
Password string `form:"password" binding:"required,min=6"`
}
type RegisterForm struct {
Username string `form:"username" binding:"required,min=3,max=20"`
Email string `form:"email" binding:"required,email"`
Password string `form:"password" binding:"required,min=6"`
}
type ProfileForm struct {
Name string `form:"name"`
Bio string `form:"bio"`
Avatar *multipart.FileHeader `form:"avatar"`
}
func main() {
r := gin.Default()
r.POST("/login", login)
r.POST("/register", register)
r.POST("/profile", updateProfile)
r.Run(":8080")
}
func login(c *gin.Context) {
var form LoginForm
if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if form.Username == "admin" && form.Password == "password123" {
c.JSON(http.StatusOK, gin.H{
"message": "登录成功",
"token": "xxx",
})
} else {
c.JSON(http.StatusUnauthorized, gin.H{
"error": "用户名或密码错误",
})
}
}
func register(c *gin.Context) {
var form RegisterForm
if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{
"message": "注册成功",
"username": form.Username,
"email": form.Email,
})
}
func updateProfile(c *gin.Context) {
var form ProfileForm
if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
response := gin.H{
"name": form.Name,
"bio": form.Bio,
}
if form.Avatar != nil {
dst := "./uploads/" + form.Avatar.Filename
c.SaveUploadedFile(form.Avatar, dst)
response["avatar"] = form.Avatar.Filename
}
c.JSON(http.StatusOK, response)
}
这一章学习了: