一:gin介绍

在gin框架中,Engine被定义成为一个结构体,Engine代表gin框架的一个结构体定义,
其中包含了路由组、中间件、页面渲染接口、框架配置设置等相关内容。
默认的Engine可以通过gin.Default进行创建,或者使用gin.New()同样可以创建。

1.1 gin.Default()和gin.New()

engine1 = gin.Default()
engine2 = gin.New()
区别:gin.Default()和gin.New()的区别在于gin.Default也使用gin.New()创建engine实例,但是会默认使用Logger和Recovery中间件。
其中:
Logger是负责进行打印并输出日志的中间件,方便开发者进行程序调试;
Recovery中间件的作用是如果程序执行过程中遇到panic中断了服务,则Recovery会恢复程序执行,并返回服务器500内部错误。
通常情况下,我们使用默认的gin.Default创建Engine实例。

二.路由

2.1 访问

Handle

r.Handle("GET", "/hello", func(c *gin.Context) {
//获取请求接口
fmt.Println(c.FullPath())

//获取字符串参数 浏览器调用格式://http://127.0.0.1:8889/hello?name=tom
name := c.DefaultQuery("name", "chengc9") //有name就是返回name,没有的话返回默认值“chengc9”
fmt.Println(name)

//输出到前端
c.Writer.Write([]byte("Hello ," + name))
})

封装分类

r.GET("/hello", func(c *gin.Context) {
    name := c.DefaultQuery("name", "chengc9") //DefaultQuery 2个参数
    c.JSON(200, gin.H{
        "message": name,
    })
})

原型

// GET 是 router.Handle("GET", path, handle) 的一种封装后的简写,源码:
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
    return group.handle(http.MethodGet, relativePath, handlers)
}
//其中的HandlerFunc 结构体
type HandlerFunc func(*Context)
//gin.H原型,因为在gin太经常使用了,所以定义了H
type H map[string]any
type any = interface{}

2.2url

分组

func main() {
    r:= gin.Default()
    // group: v1
    v1 := router.Group("/v1")
    {
        v1.POST("/test1", test1)
        v1.POST("/test2", test2)
    }
    // group: v2
    v2 := router.Group("/v2")
    {
        v2.POST("/test1", test1)
        v2.POST("/test2", test2)
    }
    router.Run(":80")
}

类型

#REST的含义就是客户端与Web服务器之间进行交互的时候,使用HTTP协议中的4个请求方法代表不同的动作:get,put,post,delete
func main() {
    r := gin.Default()
    r.GET("/book", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "GET",
        })
    })

    r.POST("/book", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "POST",
        })
    })

    r.PUT("/book", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "PUT",
        })
    })

    r.DELETE("/book", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "DELETE",
        })
    })
}

2.3路由解析顺序

https://www.liwenzhou.com/posts/Go/gin-sourcecode/

基数树(Radix Tree)又称为PAT位树(Patricia Trie or crit bit tree),是一种更节省空间的前缀树(Trie Tree)。对于基数树的每个节点,如果该节点是唯一的子树的话,就和父节点合并。

为了获得更好的可伸缩性,每个树级别上的子节点都按Priority(优先级)排序,其中优先级(最左列)就是在子节点(子节点、子子节点等等)中注册的句柄的数量。这样做有两个好处:

  1. 首先优先匹配被大多数路由路径包含的节点。这样可以让尽可能多的路由快速被定位。

  2. 类似于成本补偿。最长的路径可以被优先匹配,补偿体现在最长的路径需要花费更长的时间来定位,如果最长路径的节点能被优先匹配(即每次拿子节点都命中),那么路由匹配所花的时间不一定比短路径的路由长。下面展示了节点(每个-可以看做一个节点)匹配的路径:从左到右,从上到下

Radix Tree可以被认为是一棵简洁版的前缀树。我们注册路由的过程就是构造前缀树的过程,具有公共前缀的节点也共享一个公共父节点。假设我们现在注册有以下路由信息:

r := gin.Default()

r.GET("/", func1)
r.GET("/search/", func2)
r.GET("/support/", func3)
r.GET("/blog/", func4)
r.GET("/blog/:post/", func5)
r.GET("/about-us/", func6)
r.GET("/about-us/team/", func7)
r.GET("/contact/", func8)

那么我们会得到一个GET方法对应的路由树,具体结构如下:

Priority   Path             Handle
9          \                *<1>
3          ├s               nil
2          |├earch\         *<2>
1          |└upport\        *<3>
2          ├blog\           *<4>
1          |    └:post      nil
1          |         └\     *<5>
2          ├about-us\       *<6>
1          |        └team\  *<7>
1          └contact\        *<8>
上面最右边那一列每个*<数字>表示Handle处理函数的内存地址(一个指针)。从根节点遍历到叶子节点我们就能得到完整的路由表。

三.参数

3.1提取变量

path参数在url中以冒号开头的方式,如/:id//:id/:action
querystring指的是URL中?后面携带的参数,querystring参数在url中DefaultQuery(),Query()获取
//http://127.0.0.1:8080/book/2?name=chenc9&age=20
r.GET("/book/:id", func(c *gin.Context) {
    id:= c.Param("id")
    name := c.Query("name")
age := c.DefaultQuery("age",18)
//输出json结果给调用方 c.JSON(http.StatusOK, gin.H{ "message": "ok", "name": name, "id": id,
"age": age, }) })
get和post合并用r.POST,get无法接收表单参数等
表单参数在url中以PostForm(),DefaultPostForm()获取
r.POST("/post", getPost)
func getPost(c *gin.Context) { id := c.Query("id") page := c.DefaultQuery("page", "0") name := c.PostForm("name") message := c.DefaultPostForm("message", "信息") c.JSON(http.StatusOK, gin.H{ "id": id, "page": page, "name": name, "message": message, }) }

 

posted on 2023-02-06 20:10  聪神carry  阅读(83)  评论(0编辑  收藏  举报