gin框架
2025-12-11
gin框架
快速入门
初始化go mod
go mod init <项目名>
下载gin依赖
go get -u github.com/gin-gonic/gin
创建一个example.go:
package main
import "github.com/gin-gonic/gin"
func main() {
router := gin.Default()
router.GET("/whoami", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello Yuy0ung",
})
})
router.Run(":5003") //在5003端口监听并启动服务
}
运行:
go run example.go
访问127.0.0.1:5003

包
package main
导入
import (
"github.com/gin-gonic/gin"
"github.com/thinkerou/favicon"
)
主函数
启动
启动到5003端口,一般在主函数最后
r.Run(":5003")
基础资源
r := gin.Default()
r.Static("/static", "./static")
r.Use(favicon.New("./static/favicon.ico"))
首页
r.GET("/index", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "index",
})
})
404
r.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{
"message": "no route",
})
})
get传参
// get传参
r.GET("/user", func(c *gin.Context) {
username, ok := c.GetQuery("user")
if !ok {
c.JSON(200, gin.H{
"message": "need a username",
})
return
}
password := c.DefaultQuery("pass", "123456")
c.JSON(200, gin.H{
"message": "get",
"username": username,
"password": password,
})
})
路径传参
// 路径传参
r.GET("/ctf/:name", func(c *gin.Context) {
name := c.Param("name")
c.JSON(200, gin.H{
"message": "CTF就该学" + name,
})
})
json传参
// json传参
r.POST("/json", func(c *gin.Context) {
var user struct {
Name string `json:"name"`
Pass string `json:"pass"`
}
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(400, gin.H{
"message": "参数错误",
})
}
c.JSON(200, gin.H{
"name": user.Name,
"pass": user.Pass,
})
})
静态html页面
// 静态页面
r.GET("/", func(c *gin.Context) {
c.HTML(200, "index.html", gin.H{
"title": "Gin",
})
})
重定向到外站
//重定向到cnblogs
r.GET("/blog", func(c *gin.Context) {
c.Redirect(302, "www.cnblogs.com/yuy0ung/")
})
跳转到页面
r.POST("/tologin", func(c *gin.Context) {
c.Request.URL.Path = "/login"
r.HandleContext(c)
})
登录
r.POST("/login", func(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
// username := c.Query("username")
// password := c.Query("password")
if username == "admin" && password == "admin" {
c.JSON(200, gin.H{
"status": "ok",
"message": "登录成功",
})
} else {
c.JSON(200, gin.H{
"status": "error",
})
}
})
文件上传
配合前端使用:
//文件上传页面
r.GET("/upload", func(c *gin.Context) {
c.HTML(200, "upload.html", gin.H{
"title": "上传文件",
})
})
r.POST("/upload", func(c *gin.Context) {
//从请求中读取文件
file, err := c.FormFile("file")
if err != nil {
c.JSON(500, gin.H{
"message": "上传文件失败",
})
return
}
//保存文件至./files
err = c.SaveUploadedFile(file, "./files/"+file.Filename)
if err != nil {
c.JSON(500, gin.H{
"message": "保存文件失败",
})
return
}
c.JSON(200, gin.H{
"message": "上传成功",
})
})
路由组
就是平时见到的/api/v1/xxx那种,可以嵌套
//路由组
v1 := r.Group("/api")
{
v1.GET(/whoami", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Yuy0ung",
})
})
//嵌套
user := v1.Group("/user")
{
user.GET("/1", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "user1",
})
})
user.GET("/2", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "user2",
})
})
}
}
中间件
可多层:
// 定义中间件
func auth(c *gin.Context) {
fmt.Println("auth in")
c.Next()
fmt.Println("auth out")
}
func status(c *gin.Context) {
fmt.Println("status in")
c.Next()
fmt.Println("status out")
}
func main() {
r := gin.Default()
r.Static("/static", "./static")
r.Use(favicon.New("./static/favicon.ico"))
r.GET("/auth", auth, status, func(c *gin.Context) {
fmt.Println("authpage in")
c.JSON(200, gin.H{
"message": "auth",
})
})
//.......
}
全局注册:

路由组注册:

传递信息:

访问auth路由的输出顺序:
auth in
status in
authpage in
ok
status out
auth out
携程传参:

这里的携程函数时异步的,不会阻塞主请求流程,执行时机由 Go runtime 调度器决定,所以通常会“延迟”,表现为最后才打印