gin路由相关方法

c.Request.URL.Path 拿到请求的路径

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
104
105
106
107
108
109
110
111
112
113
114
115
116
package main

import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)

//路由重定向,请求转发,ANY ,NoRoute,路由组
func main() {
r := gin.Default()

// ---------------路由重定向(到其他网址)---------------------
r.GET("/index", func(c *gin.Context) {
//c.IndentedJSON(200,gin.H{
// "status":"ok",
//})
// 重定向到另一个地址
c.Redirect(http.StatusMovedPermanently, "https://dashen.tech")
})



// ---------------转发(到其他接口)---------------------
r.GET("/a", func(c *gin.Context) {
// 跳转到 /b对应的路由; 地址栏的URL不会变,是请求转发 (而上面是**重定向**到https://dashen.tech,地址栏的地址改变了)
c.Request.URL.Path = "/b" //把请求的URL修改
r.HandleContext(c) //继续后续的处理
})

r.GET("/b", func(context *gin.Context) {
context.IndentedJSON(200, gin.H{
"status": "这是b路径,请求成功!",
})
})




// ---------------Any: 任意http method(适用于restful,因为有同名的不同http method的方法)---------------------
// 路径为/test的,不管是GET还是POST或者PUT等,均路由到这里
r.Any("/test", func(c *gin.Context) {
switch c.Request.Method {
case http.MethodGet:
c.IndentedJSON(200, gin.H{
"info": "api为/test,GET方式~",
})

case "POST":
c.IndentedJSON(200, gin.H{
"info": "api为/test,POST方式~",
})

}
})




// --------------------NoRoute: 当匹配不到路径时到这里(其实gin默认有个404,取代之)--------------------
r.NoRoute(func(c *gin.Context) {
c.IndentedJSON(http.StatusNotFound, gin.H{
"msg": "任何没有匹配到的路径都会走到这里...(可以重定向到 寻找走丢儿童的网站)",
})
})




// // ----------------Group: 路由组--------------------
//把公用的前缀提取出来,创建一个路由组
userGroup := r.Group("/user")
{ //通常加一个大括号 让代码看起来更有调理

userGroup.GET("/getName", func(context *gin.Context) {
//等价于 /user/getname
context.IndentedJSON(http.StatusOK, gin.H{
"name": "张三",
})
})
userGroup.GET("/getGender", func(context *gin.Context) {
context.IndentedJSON(200, gin.H{
"gender": "男",
})
})

userGroup.POST("/updateAvatar", func(context *gin.Context) {
context.IndentedJSON(http.StatusOK, gin.H{
"msg": "头像更新成功",
})
})

// 可以嵌套路由组
// 即 /user/address
addressGroup := userGroup.Group("/address")

// 即/user/address/city
addressGroup.GET("/city", func(c *gin.Context) {
c.IndentedJSON(200, gin.H{
"city": "阿姆斯特丹",
})
})
}



fmt.Println("路由规则初始化完毕")
r.Run()

//go func() {
// r.Run()
//}()

//select {}

}

路由重定向



转发



Any: 捕获同名接口的任意http method


多方式匹配,包括:

GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE


NoRoute: 当匹配不到路径时到这里



路由组



默认区分大小写


通配符匹配


对于接口 /v1/say/xxxx接口(POST方法,参数为body里传一个name类型的json),当say后面为任意字符时,均路由到helloHandler方法进行处理

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
package main

import (
"fmt"
"net/http"

"github.com/gin-gonic/gin"
)

// Param 请求参数
type Param struct {
Name string `json:"name"`
}

// helloHandler /hello请求处理函数
func helloHandler(c *gin.Context) {
var p Param
if err := c.ShouldBindJSON(&p); err != nil {
c.JSON(http.StatusOK, gin.H{
"msg": "name参数缺失",
})
return
}
c.JSON(http.StatusOK, gin.H{
"msg": fmt.Sprintf("hello %s", p.Name),
})
}

// SetupRouter 路由
func SetupRouter() *gin.Engine {
router := gin.Default()
//router.POST("/v1/say/hello", helloHandler)
//router.POST("/v1/say/hello1", helloHandler)
//router.POST("/v1/say/hello3", helloHandler)
//router.POST("/v1/say/asdfg", helloHandler)

// 需要/v1/task/后面任意路径,均路由到 helloHandler
router.POST("/v1/say/*any678", helloHandler)
return router
}

func main() {
g := SetupRouter()
g.Run() // listen and serve on 0.0.0.0:8080
}


*需要加任意字符,但不能不加(只写*的话会报错)


参考:

Gin框架 路由重定向,请求转发,ANY ,NoRoute,路由组

我给 gin 提交了一行代码

Gin group级别的NoRoute

未知调用方式,静态资源返回,静态资源目录等,可参考 Golang Gin 框架 Route备注




两种写法的比较


1
2
3
4
5
6
7
8
9
r.Run()



go func() {
r.Run()
}()

select {}

第一种方式是同步的,上面的所有路由都加载完,才会运行服务

第二种方式是异步的,假设有这样一种情况,前面的路由解析都很快,但在解析最后几个路由时,特别慢(当然现实情况不太可能)。 那可以把r.Run()以异步的形式写在最上面,即启动服务和加载路由同步进行。 那前面已解析的路由就可以访问了

如:

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
104
105
package main

import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"time"
)

//路由重定向,请求转发,ANY ,NoRoute,路由组
func main() {
r := gin.Default()

go func() {
r.Run()
}()

// ---------------路由重定向(到其他网址)---------------------
r.GET("/index", func(c *gin.Context) {
//c.IndentedJSON(200,gin.H{
// "status":"ok",
//})
// 重定向到另一个地址
c.Redirect(http.StatusMovedPermanently, "https://dashen.tech")
})

// ---------------转发(到其他接口)---------------------
r.GET("/a", func(c *gin.Context) {
// 跳转到 /b对应的路由; 地址栏的URL不会变,是请求转发 (而上面是**重定向**到https://dashen.tech,地址栏的地址改变了)
c.Request.URL.Path = "/b" //把请求的URL修改
r.HandleContext(c) //继续后续的处理
})

r.GET("/b", func(context *gin.Context) {
context.IndentedJSON(200, gin.H{
"status": "这是b路径,请求成功!",
})
})

// ---------------Any: 任意http method(适用于restful,因为有同名的不同http method的方法)---------------------
// 路径为/test的,不管是GET还是POST或者PUT等,均路由到这里
r.Any("/test", func(c *gin.Context) {
switch c.Request.Method {
case http.MethodGet:
c.IndentedJSON(200, gin.H{
"info": "api为/test,GET方式~",
})

case "POST":
c.IndentedJSON(200, gin.H{
"info": "api为/test,POST方式~",
})

}
})

time.Sleep(86400 * time.Second) // 假设下面的路由1天后才会解析

// --------------------NoRoute: 当匹配不到路径时到这里(其实gin默认有个404,取代之)--------------------
r.NoRoute(func(c *gin.Context) {
c.IndentedJSON(http.StatusNotFound, gin.H{
"msg": "任何没有匹配到的路径都会走到这里...(可以重定向到 寻找走丢儿童的网站)",
})
})

// ----------------Group: 路由组--------------------
//把公用的前缀提取出来,创建一个路由组
userGroup := r.Group("/user")
{ //通常加一个大括号 让代码看起来更有调理

userGroup.GET("/getName", func(context *gin.Context) {
//等价于 /user/getname
context.IndentedJSON(http.StatusOK, gin.H{
"name": "张三",
})
})
userGroup.GET("/getGender", func(context *gin.Context) {
context.IndentedJSON(200, gin.H{
"gender": "男",
})
})

userGroup.POST("/updateAvatar", func(context *gin.Context) {
context.IndentedJSON(http.StatusOK, gin.H{
"msg": "头像更新成功",
})
})

// 可以嵌套路由组
// 即 /user/address
addressGroup := userGroup.Group("/address")

// 即/user/address/city
addressGroup.GET("/city", func(c *gin.Context) {
c.IndentedJSON(200, gin.H{
"city": "阿姆斯特丹",
})
})
}

fmt.Println("路由规则初始化完毕")

select {}

}

可见,已解析的路由可正常访问,未解析的访问则会404