美文网首页
Gin基本使用(一)

Gin基本使用(一)

作者: 强某某 | 来源:发表于2020-08-06 09:25 被阅读0次

    Gin框架介绍

    Gin框架安装与使用

    • 安装: go get -u github.com/gin-gonic/gin
    • import "github.com/gin-gonic/gin"
    package main
    import "github.com/gin-gonic/gin"
    func main() {
        //Default返回一个默认的路由引擎
        r := gin.Default()
        r.GET("/ping", func(c *gin.Context) {
            //输出json结果给调用方
            c.JSON(200, gin.H{
                "message": "pong",
            })
        })
        r.Run(":9090") // 默认:listen and serve on 0.0.0.0:8080
    }
    

    支持restful风格的API

    func main() {
        //Default返回一个默认的路由引擎
        r := gin.Default()
        r.GET("/ping", func(c *gin.Context) {
            //输出json结果给调用方
            c.JSON(200, gin.H{
                "message": "pong",
            })
        })
        r.POST("/ping", func(c *gin.Context) {
            //输出json结果给调用方
            c.JSON(200, gin.H{
                "message": "pong",
            })
        })
        r.Run() // listen and serve on 0.0.0.0:8080
    }
    

    参数传递

    • 通过querystring传递, 比如: /user/search?username=少林&address=北京
    func main() {
        //Default返回一个默认的路由引擎
        r := gin.Default()
        r.GET("/user/search", func(c *gin.Context) {
            //username := c.DefaultQuery("username", "少林")
            username = c.Query("username")
            address := c.Query("address")
            //输出json结果给调用方
            c.JSON(200, gin.H{
                "message":  "pong",
                "username": username,
                "address":  address,
            })
        })
        r.Run() // listen and serve on 0.0.0.0:8080
    }
    
    • 通过路径传递, 比如: /user/search/少林/北京
    func main() {
        //Default返回一个默认的路由引擎
        r := gin.Default()
        r.GET("/user/info", func(c *gin.Context) {
        //这种方式是,如果没传递则使用参数二当默认值
            //username := c.DefaultQuery("username", "少林")
            username = c.Query("username")
            address := c.Query("address")
            //输出json结果给调用方
            c.JSON(200, gin.H{
                "message":  "pong",
                "username": username,
                "address":  address,
            })
        })
        r.Run() // listen and serve on 0.0.0.0:8080
    }
    
    • 获取表单提交
    func testPostForm(c *gin.Context) {
        name := c.PostForm("name") //获取表单提交的数据
        c.JSON(200, gin.H{
            "message": "test",
            name:      name,
        })
    }
    
    • 单个文件上传
    func main() {
        router := gin.Default()
        // Set a lower memory limit for multipart forms (default is 32 MiB)
        // router.MaxMultipartMemory = 8 << 20 // 8 MiB
        router.POST("/upload", func(c *gin.Context) {
            // single file
            file, err := c.FormFile("file")
            if err != nil {
                c.JSON(http.StatusInternalServerError, gin.H{
                    "message": err.Error(),
                })
                return
            }
            log.Println(file.Filename)
            dst := fmt.Sprintf("C:/tmp/%s", file.Filename)
            // Upload the file to specific dst.
            c.SaveUploadedFile(file, dst)
            c.JSON(http.StatusOK, gin.H{
                "message": fmt.Sprintf("'%s' uploaded!", file.Filename),
            })
        })
        router.Run(":8080")
    }
    
    • 多文件上传
    func main() {
        router := gin.Default()
        // Set a lower memory limit for multipart forms (default is 32 MiB)
        // router.MaxMultipartMemory = 8 << 20 // 8 MiB
        router.POST("/upload", func(c *gin.Context) {
            // Multipart form
            form, _ := c.MultipartForm()
            files := form.File["file"]
            for index, file := range files {
                log.Println(file.Filename)
                dst := fmt.Sprintf("C:/tmp/%s_%d", file.Filename, index)
                c.SaveUploadedFile(file, dst)
            }
            c.JSON(http.StatusOK, gin.H{
                "message": fmt.Sprintf("%d files uploaded!", len(files)),
            })
        })
        router.Run(":8080")
    }
    

    路由分组

    func login(ctx *gin.Context) {
        ctx.JSON(200, gin.H{
            "message": "success",
        })
    }
    func submit(ctx *gin.Context) {
        ctx.JSON(200, gin.H{
            "message": "success",
        })
    }
    func main() {
        //Default返回一个默认的路由引擎
        router := gin.Default()
        // Simple group: v1
        v1 := router.Group("/v1")
        {
            v1.POST("/login", login)
            v1.POST("/submit", submit)
        }
        // Simple group: v2
        v2 := router.Group("/v2")
        {
            v2.POST("/login", login)
            v2.POST("/submit", submit)
        }
        router.Run(":8080")
    }
    

    简单案例

    package main
    
    import "github.com/gin-gonic/gin"
    
    func pingHandle(c *gin.Context) {
        // c.DefaultQuery("name")
        name := c.Query("name")
        c.JSON(200, gin.H{
            "message": "pong",
            name:      name,
        })
    }
    func testHandle(c *gin.Context) {
        name := c.Param("name")
        c.JSON(200, gin.H{
            "message": "test",
            name:      name,
        })
    }
    func testPostForm(c *gin.Context) {
        name := c.PostForm("name") //获取表单提交的数据
        c.JSON(200, gin.H{
            "message": "test",
            name:      name,
        })
    }
    
    //文件可能很大,gin默认内存最大文件是32M,超出部分则流形式一点点读,也可以设置
    // router.MaxMultipartMemory = 8 << 20 // 8 MiB  
    
    func main() {
        r := gin.Default()
        r.GET("ping", pingHandle)
        r.GET("/test/:name/:age", testHandle)
        r.GET("/test/form", testHandle)
        r.Run(":9090") //默认不传递则是9090
    }
    

    Gin框架参数绑定

    • 为什么要参数绑定,本质上是方便,提高开发效率
      • 通过反射的机制,自动提取querystring、form表单、json、xml等参数到struct中
      • 通过http协议中的context type,识别是json、xml或者表单
      • 该种方式很全能,可以识别各种传参,而且使用简单,推荐
    package main
    import (
    "net/http"
    "github.com/gin-gonic/gin"
    )
    
    // Binding from JSON
    type Login struct {
        User     string `form:"user" json:"user" binding:"required"`
        Password string `form:"password" json:"password" binding:"required"`
    }
    
    func main() {
        router := gin.Default()
        // Example for binding JSON ({"user": "manu", "password": "123"})
        router.POST("/loginJSON", func(c *gin.Context) {
            var login Login
            if err := c.ShouldBindJSON(&login); err == nil {
                c.JSON(http.StatusOK, gin.H{
                    "user":     login.User,
                    "password": login.Password,
                })
            } else {
                c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            }
        })
        // Example for binding a HTML form (user=manu&password=123)
        router.POST("/loginForm", func(c *gin.Context) {
            var login Login
            // This will infer what binder to use depending on the content-type header.
            if err := c.ShouldBind(&login); err == nil {
                c.JSON(http.StatusOK, gin.H{
                    "user":     login.User,
                    "password": login.Password,
                })
            } else {
                c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            }
        })
        // Example for binding a HTML querystring (user=manu&password=123)
        router.GET("/loginForm", func(c *gin.Context) {
            var login Login
            if err := c.ShouldBind(&login); err == nil {
                c.JSON(http.StatusOK, gin.H{
                    "user":     login.User,
                    "password": login.Password,
                })
            } else {
                c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            }
        })
        router.Run(":8080")
    }
    

    Gin框架渲染

    • 渲染json
    package main
    import (
    "net/http"
    "github.com/gin-gonic/gin"
    )
    func main() {
        r := gin.Default()
        // gin.H is a shortcut for map[string]interface{}
        r.GET("/someJSON", func(c *gin.Context) {
            //第一种方式,自己拼json
            c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
        })
        r.GET("/moreJSON", func(c *gin.Context) {
            //第二种方式,自动序列化
            // You also can use a struct
            var msg struct {
                Name    string `json:"user"`
                Message string
                Number  int
            }
            msg.Name = "Lena"
            msg.Message = "hey"
            msg.Number = 123
            // 此处会自动序列化结构体然后传输
            c.JSON(http.StatusOK, msg)
        })
        // Listen and serve on 0.0.0.0:8080
        r.Run(":8080")
    }
    
    • 渲染xml
    package main
    import (
    "net/http"
    "github.com/gin-gonic/gin"
    )
    
    func main() {
        r := gin.Default()
        r.GET("/moreXML", func(c *gin.Context) {
            // You also can use a struct
            type MessageRecord struct {
                Name    string
                Message string
                Number  int
            }
            var msg MessageRecord
            msg.Name = "Lena"
            msg.Message = "hey"
            msg.Number = 123
            c.XML(http.StatusOK, msg)
        })
        // Listen and serve on 0.0.0.0:8080
        r.Run(":8080")
    }
    
    • 渲染模板
    import (
    "net/http"
    "github.com/gin-gonic/gin"
    )
    func main() {
        router := gin.Default()
        router.LoadHTMLGlob("templates/**/*")
        router.GET("/posts/index", func(c *gin.Context) {
            c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
                "title": "Posts",
            })
        })
        router.GET("/users/index", func(c *gin.Context) {
            c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
                "title": "Users",
            })
        })
        router.Run(":8080")
    }
    

    Gin框架中间件

    • Gin框架允许在请求处理过程中,加入用户自己的钩子函数。这个钩子函数就叫中间件
    • 因此,可以使用中间件处理一些公共业务逻辑,比如耗时统计,日志打印,登陆校验.

    编写自己的中间件

    • Use方式使用
    • 中间件函数只要返回值是参数是c *gin.Context即可
    • 中间件使用可以使用gin.New()或gin.Default(),default默认包含两个中间件,错误输出中间件,请求时间中间件
    func StatCost() gin.HandlerFunc {
        return func(c *gin.Context) {
            t := time.Now()
            //可以设置一些公共参数
            c.Set("example", "12345")
            //等其他中间件先执行
            c.Next()
            //获取耗时
            latency := time.Since(t)
            log.Print(latency)
        }
    }
    func main() {
        //r := gin.New()
        r := gin.Default()
        r.Use(StatCost())
        r.GET("/test", func(c *gin.Context) {
            example := c.MustGet("example").(string)
            // it would print: "12345"
            log.Println(example)
            c.JSON(http.StatusOK, gin.H{
                "message": "success",
            })
        })
        // Listen and serve on 0.0.0.0:8080
        r.Run(":8080")
    }
    

    Gin框架路由原理

    package main
    import "github.com/gin-gonic/gin"
    func index(ctx *gin.Context) {
        ctx.JSON(200, gin.H{
            "message": "index",
        })
    }
    func main() {
        //Default返回一个默认的路由引擎
        router := gin.Default()
        router.POST("/", index)
        router.POST("/search", index)
        router.POST("/support", index)
        router.POST("/blog/:post", index)
        router.POST("/about", index)
        router.POST("/contact", index)
        router.Run(":8080")
    }
    
    • 生成的前缀树,如下所示


      2.jpg

    相关文章

      网友评论

          本文标题:Gin基本使用(一)

          本文链接:https://www.haomeiwen.com/subject/pxxzrktx.html