zoukankan      html  css  js  c++  java
  • Gin篇:Gin基础

    安装Gin

    1、配置代理

    请查看:https://github.com/goproxy/goproxy.cn/blob/master/README.zh-CN.md

    go env -w GO111MODULE=on
    go env -w GOPROXY=https://goproxy.cn,direct

    2、go get -u -v github.com/gin-gonic/gin

    -v:打印出被构建的代码包的名字
    -u:已存在相关的代码包,强行更新代码包及其依赖包

    3.部分包无法安装

    crypto无法下载解决方式:
    1.进入$GOPATH(你的安装go 的路径)
    2.进入 $GOPATH/src, 创建文件夹 golang.org, 以及子文件夹 golang.org/x
    3.进$GOPATH/golang.org/x 使用如下命令:
    4.git clone https://github.com/golang/crypto.git
    protobuf无法下载解决方式:
    1.进入$GOPATH(你的安装go 的路径)
    2.进入 $GOPATH/src, 创建文件夹 google.golang.org,以及子文件google.golang.org/protobuf
    3.将 google.golang.org/protobuf 包对应的github上的代码下载下来,github地址:https://github.com/protocolbuffers/protobuf-go 
    4.将下载下来的protobuf-go/目录下的全部文件复制到 "google.golang.org/protobuf "中
    

      

    第一个Gin程序

    package main
    
    import "github.com/gin-gonic/gin"
    
    func main() {
    	r := gin.Default()
    	r.GET("/ping", func(c *gin.Context) {
    		c.JSON(200, gin.H{
    			"message": "pong",
    		})
    	})
    	r.Run(":8200") // listen and serve on 0.0.0.0:8200
    }
    1. 首先,我们使用了gin.Default()生成了一个实例,这个实例即 WSGI 应用程序。
    2. 接下来,我们使用r.Get("/", ...)声明了一个路由,告诉 Gin 什么样的URL 能触发传入的函数,这个函数返回我们想要显示在用户浏览器中的信息。
    3. 最后用 r.Run()函数来让应用运行在本地服务器上,默认监听端口是 8200,可以传入参数设置端口,例如r.Run(":9999")即运行在 9999端口。
    [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
    
    [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
     - using env:	export GIN_MODE=release
     - using code:	gin.SetMode(gin.ReleaseMode)
    
    [GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
    [GIN-debug] Listening and serving HTTP on :8000
    

     

    路由(Route)

    路由方法有 GET, POST, PUT, PATCH, DELETE 和 OPTIONS,还有Any,可匹配以上任意类型的请求。

    func main() {
        // Disable Console Color
        // gin.DisableConsoleColor()
    
        // 使用默认中间件创建一个gin路由器
        // logger and recovery (crash-free) 中间件
        router := gin.Default()
    
        router.GET("/someGet", getting)
        router.POST("/somePost", posting)
        router.PUT("/somePut", putting)
        router.DELETE("/someDelete", deleting)
        router.PATCH("/somePatch", patching)
        router.HEAD("/someHead", head)
        router.OPTIONS("/someOptions", options)
    
        // 默认启动的是 8080端口,也可以自己定义启动端口
        router.Run()
        // router.Run(":3000") for a hard coded port
    }

    解析路径参数

    func main() {
        router := gin.Default()
    
        // 此规则能够匹配/user/john这种格式,但不能匹配/user/ 或 /user这种格式
        router.GET("/user/:name", func(c *gin.Context) {
            name := c.Param("name")
            c.String(http.StatusOK, "Hello %s", name)
        })
    
        // 但是,这个规则既能匹配/user/john/格式也能匹配/user/john/send这种格式
        // 如果没有其他路由器匹配/user/john,它将重定向到/user/john/
        router.GET("/user/:name/*action", func(c *gin.Context) {
            name := c.Param("name")
            action := c.Param("action")
            message := name + " is " + action
            c.String(http.StatusOK, message)
        })
    
        router.Run(":8080")
    }

    获取Get参数

    func main() {
        router := gin.Default()
    
        // 匹配的url格式:  /welcome?firstname=Jane&lastname=Doe
        router.GET("/welcome", func(c *gin.Context) {
            firstname := c.DefaultQuery("firstname", "Guest")
            lastname := c.Query("lastname") // 是 c.Request.URL.Query().Get("lastname") 的简写
    
            c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
        })
        router.Run(":8080")
    }
    

    获取Post参数

    func main() {
        router := gin.Default()
    
        router.POST("/form_post", func(c *gin.Context) {
            message := c.PostForm("message")
            nick := c.DefaultPostForm("nick", "anonymous") // 此方法可以设置默认值
    
            c.JSON(200, gin.H{
                "status":  "posted",
                "message": message,
                "nick":    nick,
            })
        })
        router.Run(":8080")
    }

    Get + Post 混合

    示例:
    POST /post?id=1234&page=1 HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    name=manu&message=this_is_great
    func main() {
        router := gin.Default()
    
        router.POST("/post", func(c *gin.Context) {
    
            id := c.Query("id")
            page := c.DefaultQuery("page", "0")
            name := c.PostForm("name")
            message := c.PostForm("message")
    
            fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
        })
        router.Run(":8080")
    }
    结果:id: 1234; page: 1; name: manu; message: this_is_great

    路由分组

    func main() {
        router := gin.Default()
    
        // Simple group: v1
        v1 := router.Group("/v1")
        {
            v1.POST("/login", loginEndpoint)
            v1.POST("/submit", submitEndpoint)
            v1.POST("/read", readEndpoint)
        }
    
        // Simple group: v2
        v2 := router.Group("/v2")
        {
            v2.POST("/login", loginEndpoint)
            v2.POST("/submit", submitEndpoint)
            v2.POST("/read", readEndpoint)
        }
    
        router.Run(":8080")
    }

     

    上传文件

    单个文件

    r.POST("/upload1", func(c *gin.Context) {
    	file, _ := c.FormFile("file")
    	// c.SaveUploadedFile(file, dst)
    	c.String(http.StatusOK, "%s uploaded!", file.Filename)
    })

    多个文件

    r.POST("/upload2", func(c *gin.Context) {
    	// Multipart form
    	form, _ := c.MultipartForm()
    	files := form.File["upload[]"]
    
    	for _, file := range files {
    		log.Println(file.Filename)
    		// c.SaveUploadedFile(file, dst)
    	}
    	c.String(http.StatusOK, "%d files uploaded!", len(files))
    })
    

      

    中间件(Middleware)

    // 作用于全局
    r.Use(gin.Logger())
    r.Use(gin.Recovery())
    
    // 作用于单个路由
    r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
    
    // 作用于某个组
    authorized := r.Group("/")
    authorized.Use(AuthRequired())
    {
    	authorized.POST("/login", loginEndpoint)
    	authorized.POST("/submit", submitEndpoint)
    无中间件启动使用
    r := gin.New()
    
    // 默认启动方式,包含 Logger、Recovery 中间件
    r := gin.Default()
    func main() {
        // 创建一个不包含中间件的路由器
        r := gin.New()
    
        // 全局中间件
        // 使用 Logger 中间件
        r.Use(gin.Logger())
    
        // 使用 Recovery 中间件
        r.Use(gin.Recovery())
    
        // 路由添加中间件,可以添加任意多个
        r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
    
        // 路由组中添加中间件
        // authorized := r.Group("/", AuthRequired())
        // exactly the same as:
        authorized := r.Group("/")
        // per group middleware! in this case we use the custom created
        // AuthRequired() middleware just in the "authorized" group.
        authorized.Use(AuthRequired())
        {
            authorized.POST("/login", loginEndpoint)
            authorized.POST("/submit", submitEndpoint)
            authorized.POST("/read", readEndpoint)
    
            // nested group
            testing := authorized.Group("testing")
            testing.GET("/analytics", analyticsEndpoint)
        }
    
        // Listen and serve on 0.0.0.0:8080
        r.Run(":8080")
    }

    写日志文件

    func main() {
        // 禁用控制台颜色
        gin.DisableConsoleColor()
    
        // 创建记录日志的文件
        f, _ := os.Create("gin.log")
        gin.DefaultWriter = io.MultiWriter(f)
    
        // 如果需要将日志同时写入文件和控制台,请使用以下代码
        // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
    
        router := gin.Default()
        router.GET("/ping", func(c *gin.Context) {
            c.String(200, "pong")
        })
    
        router.Run(":8080")
    } 

    自定义日志格式

    func main() {
        router := gin.New()
    
        // LoggerWithFormatter 中间件会将日志写入 gin.DefaultWriter
        // By default gin.DefaultWriter = os.Stdout
        router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
    
            // 你的自定义格式
            return fmt.Sprintf("%s - [%s] "%s %s %s %d %s "%s" %s"
    ",
                    param.ClientIP,
                    param.TimeStamp.Format(time.RFC1123),
                    param.Method,
                    param.Path,
                    param.Request.Proto,
                    param.StatusCode,
                    param.Latency,
                    param.Request.UserAgent(),
                    param.ErrorMessage,
            )
        }))
        router.Use(gin.Recovery())
    
        router.GET("/ping", func(c *gin.Context) {
            c.String(200, "pong")
        })
    
        router.Run(":8080")
    }

    输出:

    ::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
    

      

     

  • 相关阅读:
    颠倒的价牌|2013年蓝桥杯A组题解析第四题-fishers
    振兴中华|2013年蓝桥杯A组题解析第三题-fishers
    排它平方数|2013年蓝桥杯A组题解析第二题-fishers
    L2-001:dijskstra + 多条最短路径 + 记录中间路径
    2018 蓝桥杯省赛 B 组模拟赛(五)
    差分数组|小a的轰炸游戏-牛客317E
    差分数组
    线性基
    transformer中自注意力和多头注意力的pytorch实现
    transformer中的位置嵌入pytorch代码
  • 原文地址:https://www.cnblogs.com/-wenli/p/13748224.html
Copyright © 2011-2022 走看看