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

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方法进行处理

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备注




两种写法的比较


    r.Run()

    和

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

    select {}

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

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

如:

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

本文由mdnice多平台发布


好文收藏
38 声望6 粉丝

好文收集