• gin框架常见用法大全


    Gin是go语言的Web框架,结合go自带的第三方库net/http,性能不错。

    gin获取Get参数:DefaultQuery

    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	// 默认路由
    	r := gin.Default()
    	r.GET("/user", func(c *gin.Context) {
    		name := c.DefaultQuery("name", "张三")
    		c.String(http.StatusOK, fmt.Sprintf("你好 %s", name))
    	})
    	// 8080端口
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    获取API参数:Param

    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	// 默认路由
    	r := gin.Default()
    	r.GET("/user/:name/*action", func(c *gin.Context) {
    		name := c.Param("name")
    		action := c.Param("action")
    		c.String(http.StatusOK, fmt.Sprintf("你好 %s %s", name, action))
    	})
    	// 8080端口
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    1

    获取表单参数:PostForm

    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	// 默认路由
    	r := gin.Default()
    	r.POST("/form", func(c *gin.Context) {
    		types := c.DefaultPostForm("type", "post")
    		username := c.PostForm("username")
    		password := c.PostForm("password")
    		c.String(http.StatusOK, fmt.Sprintf("用户名:%s 密码:%s type:%s", username, password, types))
    	})
    	// 8080端口
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    1

    上传文件:FormFile和SaveUploadedFile

    package main
    
    import (
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	// 默认路由
    	r := gin.Default()
    	// 限制上传最大尺寸
    	r.MaxMultipartMemory = 8 << 20
    	r.POST("/upload", func(c *gin.Context) {
    		file, err := c.FormFile("file")
    		if err != nil {
    			c.String(http.StatusServiceUnavailable, "上传文件出错")
    		}
    		c.SaveUploadedFile(file, file.Filename)
    		c.String(http.StatusOK, file.Filename)
    	})
    	// 8080端口
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    1

    上传多个文件:MultipartForm

    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	// 默认路由
    	r := gin.Default()
    	// 限制上传最大尺寸
    	r.MaxMultipartMemory = 8 << 20
    	r.POST("/upload", func(c *gin.Context) {
    		form, err := c.MultipartForm()
    		if err != nil {
    			c.String(http.StatusBadRequest,
    				fmt.Sprintf("Error: %s", err.Error()))
    		}
    		files := form.File["files"]
    		for _, file := range files {
    			if err := c.SaveUploadedFile(file, file.Filename); err != nil {
    				c.String(http.StatusBadRequest, "上传文件出错 %s", err.Error())
    			}
    		}
    		c.String(http.StatusOK, "上传%d文件成功", len(files))
    	})
    	// 8080端口
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    1

    路由分组:Group

    httproter会将所有路由规则构造一颗前缀树

    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	// 默认路由
    	r := gin.Default()
    	v1 := r.Group("v1")
    	{
    		v1.GET("/rout1", rout1)
    	}
    	{
    		v1.GET("/rout2", rout2)
    	}
    
    	v2 := r.Group("v2")
    	{
    		v2.POST("rout1", rout1)
    		v2.POST("rout2", rout2)
    	}
    	// 8080端口
    	r.Run(":8080")
    }
    
    func rout1(c *gin.Context) {
    	name := c.DefaultQuery("name", "张三")
    	c.String(http.StatusOK, fmt.Sprintf("你好! %s", name))
    }
    
    func rout2(c *gin.Context) {
    	name := c.DefaultQuery("name", "李四")
    	c.String(http.StatusOK, fmt.Sprintf("你好! %s", name))
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    1

    JSON数据绑定:ShouldBindJSON

    package main
    
    import (
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    type Login struct {
    	User     string `json:"user"`
    	Password string `json:"password"`
    }
    
    func main() {
    	r := gin.Default()
    	r.POST("loginJson", func(c *gin.Context) {
    		var json Login
    		if err := c.ShouldBindJSON(&json); err != nil {
    			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    			return
    		}
    		if json.User != "root" || json.Password != "admin" {
    			c.JSON(http.StatusForbidden, gin.H{"status": "304"})
    			return
    		}
    		c.JSON(http.StatusOK, gin.H{"status": "200"})
    	})
    	// 8080端口
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    1
    1

    表单数据绑定:Bind

    package main
    
    import (
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    type Login struct {
    	User     string `form:"username" json:"user"`
    	Password string `form:"password" json:"password"`
    }
    
    func main() {
    	r := gin.Default()
    	r.POST("loginForm", func(c *gin.Context) {
    		var form Login
    		if err := c.Bind(&form); err != nil {
    			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    			return
    		}
    		if form.User != "root" || form.Password != "admin" {
    			c.JSON(http.StatusForbidden, gin.H{"status": "304"})
    			return
    		}
    		c.JSON(http.StatusOK, gin.H{"status": "200"})
    	})
    	// 8080端口
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    1

    Uri数据绑定:ShouldBindUri

    package main
    
    import (
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    type Login struct {
    	// binding:"required"的字段,是必须字段,否则报错
    	User     string `uri:"username" binding:"required"`
    	Password string `uri:"password" binding:"required"`
    }
    
    func main() {
    	r := gin.Default()
    	r.POST("/:username/:password", func(c *gin.Context) {
    		var uri Login
    		if err := c.ShouldBindUri(&uri); err != nil {
    			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    			return
    		}
    		if uri.User != "root" || uri.Password != "admin" {
    			c.JSON(http.StatusForbidden, gin.H{"status": "304"})
    			return
    		}
    		c.JSON(http.StatusOK, gin.H{"status": "200"})
    	})
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    1

    各种数据响应格式

    package main
    
    import (
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    	"github.com/gin-gonic/gin/testdata/protoexample"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("json", func(ctx *gin.Context) {
    		ctx.JSON(http.StatusOK, gin.H{"data": "[1]", "status": 200})
    	})
    	r.GET("struct", func(ctx *gin.Context) {
    		var msg struct {
    			Data   string
    			Status int
    		}
    		msg.Data = "[2]"
    		msg.Status = 200
    		ctx.JSON(http.StatusOK, msg)
    	})
    	r.GET("xml", func(ctx *gin.Context) {
    		ctx.XML(http.StatusOK, gin.H{"data": "[3]", "status": 200})
    	})
    	r.GET("yaml", func(ctx *gin.Context) {
    		ctx.YAML(http.StatusOK, gin.H{"data": "[4]", "status": 200})
    	})
    	r.GET("protobuf", func(ctx *gin.Context) {
    		reps := []int64{int64(5)}
    		label := "label"
    		data := &protoexample.Test{
    			Label: &label,
    			Reps:  reps,
    		}
    		ctx.ProtoBuf(http.StatusOK, data)
    	})
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    1
    1
    3
    4
    5

    渲染HTML页面

    301重定向

    package main
    
    import (
    	"net/http"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/index", func(ctx *gin.Context) {
    		ctx.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")
    	})
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    1

    同步异步

    package main
    
    import (
    	"log"
    	"time"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/async", func(ctx *gin.Context) {
    		context := ctx.Copy() // 必须使用上下文副本,不能使用原始上下文
    		// 启动新的goroutine
    		go func() {
    			time.Sleep(3 * time.Second)
    			log.Println("异步执行:" + context.Request.URL.Path)
    		}()
    	})
    	r.GET("sync", func(ctx *gin.Context) {
    		time.Sleep(3 * time.Second)
    		log.Println("同步执行:" + ctx.Request.URL.Path)
    	})
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    1

    全局中间件

    package main
    
    import (
    	"fmt"
    	"net/http"
    	"time"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	r.Use(MiddleWare())
    	// {}只是为了代码规范
    	{
    		r.GET("/ce", func(ctx *gin.Context) {
    			req, _ := ctx.Get("request")
    			fmt.Println("request:", req)
    			ctx.JSON(http.StatusOK, gin.H{"reqeust": req})
    		})
    	}
    	r.Run(":8080")
    }
    
    func MiddleWare() gin.HandlerFunc {
    	return func(ctx *gin.Context) {
    		t := time.Now()
    		fmt.Println("中间件开始执行")
    		// 设置request到上下文,可以通过Get获取
    		ctx.Set("request", "中间件")
    		status := ctx.Writer.Status()
    		// 执行函数
    		ctx.Next()
    		fmt.Println("中间件执行完毕", status)
    		t2 := time.Since(t)
    		fmt.Println("time:", t2)
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    1

    1

    局部中间件

    package main
    
    import (
    	"fmt"
    	"net/http"
    	"time"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	// 全局中间件
    	// r.Use(MiddleWare())
    	// 局部中间件
    	r.GET("/ce", MiddleWare(), func(ctx *gin.Context) {
    		req, _ := ctx.Get("request")
    		fmt.Println("request:", req)
    		ctx.JSON(http.StatusOK, gin.H{"reqeust": req})
    	})
    	r.Run(":8080")
    }
    
    func MiddleWare() gin.HandlerFunc {
    	return func(ctx *gin.Context) {
    		t := time.Now()
    		fmt.Println("中间件开始执行")
    		// 设置request到上下文,可以通过Get获取
    		ctx.Set("request", "中间件")
    		status := ctx.Writer.Status()
    		// 执行函数
    		ctx.Next()
    		fmt.Println("中间件执行完毕", status)
    		t2 := time.Since(t)
    		fmt.Println("time:", t2)
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    Cookie

    package main
    
    import (
    	"fmt"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	// 全局中间件
    	// r.Use(MiddleWare())
    	// 局部中间件
    	r.GET("/cookie", func(ctx *gin.Context) {
    		cookie, err := ctx.Cookie("key_cookie")
    		if err != nil {
    			cookie = "Cookie未设置"
    			ctx.SetCookie("key_cookie", "value_cookie", 60, "/", "localhost", false, true)
    		}
    		fmt.Println("Cookie:", cookie)
    	})
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    验证码

    package main
    
    import (
    	"bytes"
    	"net/http"
    	"time"
    
    	"github.com/dchest/captcha"
    	"github.com/gin-contrib/sessions"
    	"github.com/gin-contrib/sessions/cookie"
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	// 全局中间件
    	r.Use(Session("sectet"))
    	r.GET("/captcha", func(ctx *gin.Context) {
    		Captcha(ctx, 4)
    	})
    	r.GET("/captcha/verify/:value", func(ctx *gin.Context) {
    		value := ctx.Param("value")
    		if CaptchaVerify(ctx, value) {
    			ctx.JSON(http.StatusOK, gin.H{"status": 0, "msg": "success"})
    		} else {
    			ctx.JSON(http.StatusOK, gin.H{"status": 1, "msg": "failed"})
    		}
    	})
    	r.Run(":8080")
    }
    
    func Session(keyPairs string) gin.HandlerFunc {
    	store := SessionConfig()
    	return sessions.Sessions(keyPairs, store)
    }
    
    func SessionConfig() sessions.Store {
    	sessionMaxAge := 3600
    	sessionSectet := "sectet"
    	store := cookie.NewStore([]byte(sessionSectet))
    	store.Options(sessions.Options{
    		MaxAge: sessionMaxAge,
    		Path:   "/",
    	})
    	return store
    }
    
    func Captcha(c *gin.Context, length ...int) {
    	l := captcha.DefaultLen
    	w, h := 107, 36
    	if len(length) == 1 {
    		l = length[0]
    	}
    	if len(length) == 2 {
    		w = length[1]
    	}
    	if len(length) == 3 {
    		h = length[2]
    	}
    	captchaId := captcha.NewLen(l)
    	session := sessions.Default(c)
    	session.Set("captcha", captchaId)
    	_ = session.Save()
    	_ = Serve(c.Writer, c.Request, captchaId, ".png", "zh", false, w, h)
    }
    func CaptchaVerify(c *gin.Context, code string) bool {
    	session := sessions.Default(c)
    	if captchaId := session.Get("captcha"); captchaId != nil {
    		session.Delete("captcha")
    		_ = session.Save()
    		if captcha.VerifyString(captchaId.(string), code) {
    			return true
    		} else {
    			return false
    		}
    	} else {
    		return false
    	}
    }
    func Serve(w http.ResponseWriter, r *http.Request, id, ext, lang string, download bool, width, height int) error {
    	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
    	w.Header().Set("Pragma", "no-cache")
    	w.Header().Set("Expires", "0")
    
    	var content bytes.Buffer
    	switch ext {
    	case ".png":
    		w.Header().Set("Content-Type", "image/png")
    		_ = captcha.WriteImage(&content, id, width, height)
    	case ".wav":
    		w.Header().Set("Content-Type", "audio/x-wav")
    		_ = captcha.WriteAudio(&content, id, lang)
    	default:
    		return captcha.ErrNotFound
    	}
    
    	if download {
    		w.Header().Set("Content-Type", "application/octet-stream")
    	}
    	http.ServeContent(w, r, id+ext, time.Time{}, bytes.NewReader(content.Bytes()))
    	return nil
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    1
    1
    注意:cookie要一致,表示同一个会话。

    参考链接

    https://www.topgoer.com/gin%E6%A1%86%E6%9E%B6/

  • 相关阅读:
    最新JustMedia V2.7.3主题破解版去授权WordPress主题模板
    主成分分析;主成分回归分析——Hald水泥问题;主成分分析案例——各地区普通高等教育发展水平综合评价;matlab
    【日更】 linux常用命令
    ArcGIS Engine10.2 Setup 报错
    MATLAB中polyvalm函数用法
    戴尔电脑怎么关闭开机密码?
    个人云存储:使用Cpolar和极简主义文件管理器构建的公网访问平台
    Flowable(一个开源的工作流和业务流程管理引擎)中与事件相关的一些核心概念
    python渗透测试入门——基础的网络编程工具
    Spring Boot是什么?
  • 原文地址:https://blog.csdn.net/lilongsy/article/details/127825243