• gin-基础笔记


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    前言

    gin框架的基本使用,把各个知识点拆分写成demo。


    1、get和post方法

    最简单的获取参数的方法。我还知道json映射,后续补充。

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/hi", getMsg)
    	r.POST("/hi", postMsg)
    	r.Run(":9090")
    }
    
    func getMsg(c *gin.Context) {
    	name := c.Query("name")
    	// c.String(http.StatusOK, "欢迎:%s",name)
    	c.JSON(http.StatusOK, gin.H{
    		"code": http.StatusOK,
    		"msg":  "欢迎:" + name,
    	})
    }
    
    func postMsg(c *gin.Context) {
    	name := c.DefaultPostForm("name", "lisi")
    	fmt.Println(name)
    	form, b := c.GetPostForm("name")
    	fmt.Println(form, b)
    }
    
    
    • 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

    2、重定向

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    	// 第一种应该是在某个版本被废弃了
    	/*r.GET("/hi", func(c *gin.Context) {
    		c.Redirect(http.StatpusMovedPermanently, "http://www.baidu.com")
    	})*/
    
    	r.GET("/hi", getMsg)
    	r.GET("/hello", func(c *gin.Context) {
    		c.Request.URL.Path = "/hi"
    		r.HandleContext(c)
    	})
    	r.Run(":9090")
    }
    
    func getMsg(c *gin.Context) {
    	name := c.Query("name")
    	// c.String(http.StatusOK, "欢迎:%s",name)
    	c.JSON(http.StatusOK, gin.H{
    		"code": http.StatusOK,
    		"msg":  "欢迎:" + 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

    3、获取第三方数据

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    
    	r.GET("/getThird", func(c *gin.Context) {
    		url := "http://www.baidu.com"
    		resp, err := http.Get(url)
    		if err != nil || resp.StatusCode != http.StatusOK {
    			c.Status(http.StatusServiceUnavailable)
    			return
    		}
    		body := resp.Body
    		contentLength := resp.ContentLength
    		contentType := resp.Header.Get("Content-Type")
    		c.DataFromReader(http.StatusOK, contentLength, contentType, body, nil)
    	})
    	r.Run(":9090")
    }
    
    
    • 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

    4、多形式渲染

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    
    	r.GET("/getJson", func(c *gin.Context) {
    		// JSON 使用 unicode 替换特殊 HTML 字符,例如 < 变为 \ u003c
    		c.JSON(http.StatusOK, gin.H{
    			"html": "

    hi

    "
    , }) }) r.GET("/getHTML", func(c *gin.Context) { // 如果要正常返回HTML字符,用PureJSON c.PureJSON(http.StatusOK, gin.H{ "html": "

    hi

    "
    , }) }) r.GET("/getXML", func(c *gin.Context) { type Message struct { Name string Msg string Age int } info := Message{ Name: "zhangsan", Msg: "hello", Age: 20, } c.XML(http.StatusOK, info) }) r.GET("/getYAML", func(c *gin.Context) { // 会下在一个yaml文件 c.YAML(http.StatusOK, gin.H{ "msg": "hello", }) }) r.Run(":9090") }
    • 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

    5、文件服务器

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/file", func(c *gin.Context) {
    		path := "/home/ld/workspace/study/gin-learn/2.4_file/" // 最后一个/一定要加上,否则拼接路径就不对了
    		fileName := path + c.Query("name")
    		// JSON 使用 unicode 替换特殊 HTML 字符,例如 < 变为 \ u003c
    		c.File(fileName)
    	})
    	r.Run(":9090")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    6、单文件上传

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    	r.POST("/uploadOne", func(c *gin.Context) {
    		file, err := c.FormFile("fileName")
    		if err != nil {
    			fmt.Println(err.Error())
    			c.String(http.StatusBadRequest, "文件上传错误")
    		}
    		dst := "/home/ld/workspace/study/gin-learn/2.5_file_upload_one/"
    		c.SaveUploadedFile(file, dst+file.Filename)
    		c.String(http.StatusOK, "保存成功:%s", file.Filename)
    	})
    	r.Run(":9090")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    设置请求头
    设置请求体

    7、多文件上传

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    	r.POST("/uploadMoreThanOne", func(c *gin.Context) {
    		form, err := c.MultipartForm()
    		if err != nil {
    			fmt.Println(err.Error())
    			c.String(http.StatusBadRequest, "文件上传错误")
    		}
    		files := form.File["file_key"]
    		dst := "/home/ld/workspace/study/gin-learn/2.6_file_upload_more_than_one/"
    		for _, file := range files {
    			c.SaveUploadedFile(file, dst+file.Filename)
    		}
    		c.String(http.StatusOK, "%d个文件保存成功", len(files))
    	})
    	r.Run(":9090")
    }
    
    
    • 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

    设置请求体

    8、自定义中间件

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    	"strconv"
    )
    
    func main() {
    	r := gin.Default()
    	r.Use(Middleware())
    	r.GET("/middle", func(c *gin.Context) {
    		c.String(http.StatusOK, "年龄验证成功,年龄为:%s", c.Query("age"))
    	})
    	r.Run(":9090")
    }
    
    func Middleware() gin.HandlerFunc {
    	return func(c *gin.Context) {
    		ageStr := c.Query("age")
    		age, err := strconv.Atoi(ageStr)
    		if err != nil || age < 18 {
    			c.AbortWithStatusJSON(http.StatusBadRequest, "年龄异常")
    			return
    		}
    		c.Next()
    	}
    }
    
    
    • 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

    9、登录中间件

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    	r.Use(AuthMiddleware())
    	r.GET("/middle", func(c *gin.Context) {
    		c.String(http.StatusOK, "身份验证成功,用户为:%s", c.MustGet(gin.AuthUserKey))
    	})
    	r.Run(":9090")
    }
    
    func AuthMiddleware() gin.HandlerFunc {
    	// 静态添加
    	accounts := gin.Accounts{
    		"admin": "admin",
    		"user":  "user",
    	}
    	// 动态添加
    	accounts["boss"] = "boss"
    	auth := gin.BasicAuth(accounts)
    	return auth
    }
    
    
    • 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

    10、同步异步

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    	"time"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/sync", func(c *gin.Context) {
    		sync(c)
    		c.String(http.StatusOK, "同步任务结束")
    	})
    	r.GET("/async", func(c *gin.Context) {
    		for i := 0; i < 6; i++ {
    			go async(c)
    		}
    		c.String(http.StatusOK, "异步任务结束")
    	})
    	r.Run(":9090")
    }
    
    func async(c *gin.Context) {
    	println("开始同步任务")
    	time.Sleep(3 * time.Second)
    	println("同步任务结束")
    }
    
    func sync(c *gin.Context) {
    	println("开始同步任务")
    	time.Sleep(3 * time.Second)
    	println("同步任务结束")
    }
    
    
    • 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

    11、多服务器程序运行

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"golang.org/x/sync/errgroup"
    	"net/http"
    	"time"
    )
    
    var g errgroup.Group
    
    func main() {
    	server01 := &http.Server{
    		Addr:         ":9091",
    		Handler:      router01(),
    		ReadTimeout:  5 * time.Second,
    		WriteTimeout: 10 * time.Second,
    	}
    	server02 := &http.Server{
    		Addr:         ":9092",
    		Handler:      router02(),
    		ReadTimeout:  5 * time.Second,
    		WriteTimeout: 10 * time.Second,
    	}
    	g.Go(func() error {
    		return server01.ListenAndServe()
    	})
    	g.Go(func() error {
    		return server02.ListenAndServe()
    	})
    
    	if err := g.Wait(); err != nil {
    		fmt.Println("Error: ", err)
    	}
    }
    func router01() http.Handler {
    	r := gin.Default()
    	r.GET("/router01", func(c *gin.Context) {
    		c.String(http.StatusOK, "router01")
    	})
    	return r
    }
    func router02() http.Handler {
    	r := gin.Default()
    	r.GET("/router02", func(c *gin.Context) {
    		c.String(http.StatusOK, "router02")
    	})
    	return r
    }
    
    
    • 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

    12、路由组

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    	group1 := r.Group("/group1")
    	{
    		group1.GET("/hi", getMsg)
    		group1.GET("/hello", getMsg)
    
    	}
    	group2 := r.Group("/group2")
    	group2.GET("/hi", getMsg)
    	r.Run(":9090")
    }
    
    func getMsg(c *gin.Context) {
    	name := c.Query("name")
    	// c.String(http.StatusOK, "欢迎:%s",name)
    	c.JSON(http.StatusOK, gin.H{
    		"code": http.StatusOK,
    		"msg":  "欢迎:" + 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

    13、Gin框架bind

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    // User 大写
    type User struct {
    	Name     string `json:"name" binding:"required"`
    	Password string `json:"password"`
    }
    
    func main() {
    	r := gin.Default()
    
    	r.POST("/hi", getMsg)
    	r.Run(":9090")
    }
    
    func getMsg(c *gin.Context) {
    	var user User
    	// 此处传指针
    	err := c.Bind(&user)
    	if err != nil {
    		c.JSON(http.StatusBadRequest, err.Error())
    		return
    	}
    	c.JSON(http.StatusOK, gin.H{
    		"code": http.StatusOK,
    		"msg":  "欢迎:" + user.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

    14、调用restful接口

    package main
    
    import (
    	"bytes"
    	"encoding/json"
    	"fmt"
    	"io/ioutil"
    	"net/http"
    	"time"
    )
    
    // User 大写
    type User struct {
    	Name     string `json:"name" binding:"required"`
    	Password string `json:"password"`
    }
    
    type TempData struct {
    	// Code string `json:"code"` // 不会给这个值反序列化
    	Msg string `json:"msg"`
    }
    
    func main() {
    	testApi()
    	// 应用中就是一样的道理了,解析请求体,然后调用,最后把响应体封装返回给请求端就好了
    }
    
    func testApi() {
    	url := "http://127.0.0.1:9090/hi"
    	user := User{
    		Name:     "zs",
    		Password: "123",
    	}
    	data, err := getRestfulApi(url, user, "application/json")
    	var tmp TempData
    	json.Unmarshal(data, &tmp)
    	fmt.Println(tmp, err)
    }
    
    // getRestfulApi send post request
    // url: 请求地址
    // data: post请求提交的数据
    // contentType: 请求体格式,如application/json
    // res: 请求返回的内容
    func getRestfulApi(url string, data interface{}, contentType string) ([]byte, error) {
    	// 创建调用api接口的client
    	client := &http.Client{Timeout: time.Second * 5}
    	jsonStr, _ := json.Marshal(data)
    	resp, err := client.Post(url, contentType, bytes.NewBuffer(jsonStr))
    	if err != nil {
    		fmt.Println("Error marshalling")
    		return nil, err
    	}
    	res, err := ioutil.ReadAll(resp.Body)
    	return res, err
    }
    
    
    • 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

    15、参数校验1-tag验证

    package main
    
    import (
    	"github.com/gin-gonic/gin"
    	"github.com/go-playground/validator/v10"
    	"net/http"
    	"sync"
    )
    
    var (
    	Validate *validator.Validate
    	once     sync.Once
    )
    
    // User 大写
    type User struct {
    	Name     string `json:"name" validate:"required"`
    	Age      int    `json:"age" validate:"checkAge"` // 这里是为了演示,对于数字的校验,可以直接使用最大值最小值规则
    	Password string `json:"password"`
    }
    
    // 项目里可以这样实现
    func init() {
    	once.Do(func() {
    		Validate = validator.New()
    		Validate.RegisterValidation("checkAge", checkAgeFunc)
    	})
    }
    
    func checkAgeFunc(fl validator.FieldLevel) bool {
    	if fl.Field().Int() > 18 {
    		return true
    	}
    	return false
    }
    
    func main() {
    
    	r := gin.Default()
    
    	r.POST("/hi", getMsg)
    	r.Run(":9090")
    }
    
    func getMsg(c *gin.Context) {
    	var user User
    	// 此处传指针
    	err := c.Bind(&user)
    	if err != nil {
    		c.JSON(http.StatusBadRequest, err.Error())
    		return
    	}
    	err = Validate.Struct(user)
    	if err != nil {
    		c.JSON(http.StatusBadRequest, err.Error())
    		return
    	}
    	c.JSON(http.StatusOK, gin.H{
    		"code": http.StatusOK,
    		"msg":  "欢迎:" + user.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
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    16、参数校验2-嵌套结构体验证

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"github.com/go-playground/validator/v10"
    	"net/http"
    	"sync"
    )
    
    var (
    	Validate *validator.Validate
    	once     sync.Once
    )
    
    // User 大写
    type User struct {
    	Name string    `json:"name" validate:"required"`
    	Addr []Address `json:"addresses" validate:"required,dive"`
    }
    
    type Address struct {
    	Country string `json:"country" validate:"required"`
    	City    string `json:"city" validate:"required"`
    }
    
    // 项目里可以这样实现
    func init() {
    	once.Do(func() {
    		Validate = validator.New()
    	})
    }
    
    func main() {
    	r := gin.Default()
    
    	r.POST("/hi", getMsg)
    	r.Run(":9090")
    }
    
    func getMsg(c *gin.Context) {
    	var user User
    	// 此处传指针
    	err := c.Bind(&user)
    	if err != nil {
    		c.JSON(http.StatusBadRequest, err.Error())
    		return
    	}
    	err = Validate.Struct(user)
    	if err != nil {
    		c.JSON(http.StatusBadRequest, err.Error())
    		return
    	}
    	fmt.Print("你的地址包括:")
    	for _, v := range user.Addr {
    		fmt.Print(v.Country + "-" + v.City + " ")
    	}
    	fmt.Println()
    	c.JSON(http.StatusOK, gin.H{
    		"code": http.StatusOK,
    		"msg":  "欢迎:" + user.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
    • 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

    17、swagger

    完成代码

    package main
    
    import (
    	_ "gin-learn/2.16_swagger/docs"
    	"github.com/gin-gonic/gin"
    	swaggerfiles "github.com/swaggo/files"
    	ginSwagger "github.com/swaggo/gin-swagger"
    	"net/http"
    )
    
    // User 大写
    type User struct {
    	Name     string `json:"name" binding:"required"`
    	Password string `json:"password"`
    }
    
    func main() {
    	r := gin.Default()
    	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
    	r.POST("/hi", getMsg)
    	r.Run(":9090")
    }
    
    // getMsg godoc
    // @Tags 获取信息
    // @Summary ping example
    // @Description do ping
    // @Accept json
    // @Produce json
    // @Param user body string true "用户"
    // @Success 200 {string} json "{"code":"200", "msg":  "欢迎:username"}"
    // @Router /hi [post]
    func getMsg(c *gin.Context) {
    	var user User
    	// 此处传指针
    	err := c.Bind(&user)
    	if err != nil {
    		c.JSON(http.StatusBadRequest, err.Error())
    		return
    	}
    	c.JSON(http.StatusOK, gin.H{
    		"code": http.StatusOK,
    		"msg":  "欢迎:" + user.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
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    安装:

    go install github.com/swaggo/swag/cmd/swag@latest
    
    • 1

    生成文档文件

    swag init
    
    • 1

    运行,然后打开
    http://localhost:9090/swagger/index.html

    在我操作过程中碰到一个问题,我生成的docs.go中有这样一段代码

    // SwaggerInfo holds exported Swagger Info so clients can modify it
    var SwaggerInfo = &swag.Spec{
    	Version:          "",
    	Host:             "",
    	BasePath:         "",
    	Schemes:          []string{},
    	Title:            "",
    	Description:      "",
    	InfoInstanceName: "swagger",
    	SwaggerTemplate:  docTemplate,
    	LeftDelim:        "{{",
    	RightDelim:       "}}",
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    而我的swag是v1.8.12,Spec的定义中没有LeftDelim、RightDelim,如下,导致了报错,我只能手动删除这部分,不知道哪一步出错了。

    // Spec holds exported Swagger Info so clients can modify it.
    type Spec struct {
    	Version          string
    	Host             string
    	BasePath         string
    	Schemes          []string
    	Title            string
    	Description      string
    	InfoInstanceName string
    	SwaggerTemplate  string
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    18、Gin框架cookie

    package main
    
    import (
    	"encoding/hex"
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    
    	// r.POST("/hi", getMsg)
    	r.Use(CookieMiddleware())
    	r.GET("/cookie", handleCookie)
    	r.Run(":9090")
    }
    
    func handleCookie(c *gin.Context) {
    	name := c.Query("name")
    	cookieName := "cookie_" + name
    	val, _ := c.Cookie(cookieName)
    	if val == "" {
    		c.JSON(http.StatusOK, gin.H{
    			"code": http.StatusOK,
    			"msg":  "cookie : " + cookieName,
    		})
    		return
    	}
    	// c.String(http.StatusOK, "欢迎:%s",name)
    	c.JSON(http.StatusOK, gin.H{
    		"code": http.StatusOK,
    		"msg":  "欢迎:" + cookieName + "-" + val,
    	})
    }
    
    func CookieMiddleware() gin.HandlerFunc {
    	return func(c *gin.Context) {
    		name := c.Query("name")
    		if len(name) <= 0 {
    			c.JSON(http.StatusBadRequest, gin.H{
    				"code": http.StatusBadRequest,
    				"msg":  "数据错误",
    			})
    			return
    		}
    		cookieName := "cookie_" + name
    		cookieValue := hex.EncodeToString([]byte(cookieName + "value"))
    		val, _ := c.Cookie(cookieName)
    		if val == "" {
    			c.SetCookie(cookieName, cookieValue, 3600, "/", "localhost", true, true)
    			fmt.Println("cookie already set")
    		}
    		c.Next()
    	}
    }
    
    
    • 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

    验证的时候需要手动输入cookie,如图:

    选择cookie

    填充cookie

    19、Gin框架Session

    package main
    
    import (
    	"github.com/gin-contrib/sessions"
    	"github.com/gin-contrib/sessions/cookie"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    	store := cookie.NewStore([]byte("session_secret"))
    	r.Use(sessions.Sessions("mySession", store))
    	r.GET("/session", handleSession)
    	r.Run(":9090")
    }
    
    var sessionName string
    var sessionValue string
    
    type MyOption struct {
    	sessions.Options
    }
    
    func handleSession(c *gin.Context) {
    	name := c.Query("name")
    	if len(name) <= 0 {
    		c.JSON(http.StatusBadRequest, "数据错误")
    		return
    	}
    	sessionName = "session_" + name
    	sessionValue = "session_value_" + name
    	session := sessions.Default(c)
    	sessionData := session.Get(sessionName)
    	if sessionData != sessionValue {
    		session.Set(sessionName, sessionValue)
    		o := MyOption{}
    		o.Path = "/"
    		o.MaxAge = 10 // 有效期,s
    		session.Options(o.Options)
    		session.Save() // 保存session
    		c.JSON(http.StatusOK, "首次访问,保存session")
    		return
    	}
    	c.JSON(http.StatusOK, "session: "+sessionData.(string))
    }
    
    • 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

    总结

    gin框架的基本使用

  • 相关阅读:
    redis set zset key 常用命令
    服务器数据恢复-RAID5中磁盘被踢导致阵列崩溃的服务器数据恢复案例
    葡聚糖-MAL/NHS/N3/Alkyne/SH/Biotin/CHO/OPSS/OH
    gitlab cicd问题整理
    前端—— 分层模型和应用协议
    红队常用命令速查
    【Java开发岗:SpringCould篇】
    S7net【C#】
    vue draggable组件,拖拽元素时,获取元素上在data或setup中定义的数据
    【图像处理】基于二叉树的改进SPIHT算法matlab代码
  • 原文地址:https://blog.csdn.net/i973635025/article/details/132926920