gin框架路由处理方法Handle,中间件,9种请求方式(GET, POST, PUT,DELETE... CONNECT, TRACE)使用方法,gin路由接口IRoutes解析

在gin框架中,所有的路由都是通过IRoutes接口中的Handle方法进行处理的。在我们使用gin的路由之前,非常有必要了解这个方法的定义和参数用法。因为gin支持的9种请求方式(GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, CONNECT, TRACE)都是通过该方法来完成的。

路由处理方法Handle 详解

这个方法就是用来处理http请求方法,路由地址和对应的路由处理控制器的。

方法定义: Handle(string, string, ...HandlerFunc) IRoutes

第一个参数 就是请求方式字符串,支持GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, CONNECT, TRACE 这9种请求方式,注意请求方式字符串必须是大写

第二个参数 是路由地址字符串,即用户可通过这个地址访问到相关的控制器

第三个参数HandlerFunc  这个参数是一个可变参数,他是对应的路由地址的处理控制器,可以是多个控制器,即一个路由地址可以同时转发到多个后端控制器处理。 HandlerFunc是一个函数类型,这个函数类型的定义为: type HandlerFunc func(*Context)   这个的意思就是只要是你的函数/方法的入参只有一个且是 *gin.Context 类型就可以作为路由的处理控制器函数

注意,理解这个 路由处理函数 HandlerFunc 对于使用gin框架非常重要!!! 因为gin中的所有的路由、 中间件入参都必须要符合这个HandlerFunc的定义! 即 只能有一个*gin.Context 类型的参数。

gin中间件

gin框架中的中间件,实际上就是一个符合HandlerFunc函数定义的函数/方法,即函数/方法的参数类型必须是 *gin.Context 且只能有一个参数,没有返回值。 在中间件中我们使用  c.Next() 方法来继续后续的处理, 如果要在中间件中拦截当前请求, 需要使用 c.Abort() 中断后续请求,和return返回当前请求来立即中断网络请求。

使用方法参考 : 用于gin框架的CORS中间件,解决身份凭证和通配符不能同时设置问题,可同时配置附带身份凭证的请求和*通配符,chrome插件CORS跨域请求通配符-CSDN博客

GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS请求方式使用方法

gin框架中支持的9种请求方式,GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, 这7种请求方式gin框架在IRoutes接口中都为我们定义了相应的快捷方式方法, 即

使用方法就是直接通过路由对象  r.XXX() 来使用,示例:

func main() {
    r := gin.Default()
    // GET请求, 支持的7种请求,可选项有 GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
    r.GET("/index", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "msg": "Hello world!",
        })
    })

    r.Run(":8080")
}

CONNECT, TRACE 请求方式使用方法

对于这2种请求方式,gin框架没有提供相应的快捷方法,我们可以直接通过路由对象中的 Handle方法来实现。 使用示例:

// 定义一个HandlerFunc路由处理函数 注意这里的入参只能有1个且必须是 *gin.Context
handlerFn := func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "msg": "Hello world!",
        })
    } 

// Handle路由处理方法使用示例 
r.Handle("CONNECT", "/index", handlerFn)

Any方法

gin路由接口中的Any方法在内部实际上是gin框架帮我们一起注册了全部的9个请求类型的路由到你指定的路由地址和控制器上面。参数和前面的7种请求方式是一样的,第一个参数是路由地址,第二个参数是路由处理控制器方法/函数。

Any方法源码参考:

// Any registers a route that matches all the HTTP methods.
// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes {
	for _, method := range anyMethods {
		group.handle(method, relativePath, handlers)
	}

	return group.returnObj()
}

上面的anyMethods这个变量的定义为:
    anyMethods = []string{
        http.MethodGet, http.MethodPost, http.MethodPut, http.MethodPatch,
        http.MethodHead, http.MethodOptions, http.MethodDelete, http.MethodConnect,
        http.MethodTrace,

    }

这里实际上就是go语言中http所支持的9种请求方式的常量,位于go内置包 "net/http" 中。

Match方法

这个方法实际上就是Any犯法的优化版本。他比Any方法多了一个参数,这个参数用于定义我们需要注册的方法路由。

Match方法定义参考:


// Match registers a route that matches the specified methods that you declared.
func (group *RouterGroup) Match(methods []string, relativePath string, handlers ...HandlerFunc) IRoutes {
	for _, method := range methods {
		group.handle(method, relativePath, handlers)
	}

	return group.returnObj()
}

这里的第一个参数 methods是一个字符串切片,这个切片即我们要注册的请求方法,他们的值只能是 上面的9种请求方法中的一个或者多个。

// Match路由处理方法使用示例 
r.Match([]string{"GET", "POST", "PUT", "DELETE", "HEAD"},"/index", handlerFn)

上面的示例会对路由地址 /index 一次性注册"GET", "POST", "PUT", "DELETE", "HEAD" 这5个请求方法对应的路由到handlerFn函数。

  gin框架路由接口定义参考


// IRoutes defines all router handle interface.
type IRoutes interface {
    Use(...HandlerFunc) IRoutes

    Handle(string, string, ...HandlerFunc) IRoutes
    Any(string, ...HandlerFunc) IRoutes
    GET(string, ...HandlerFunc) IRoutes
    POST(string, ...HandlerFunc) IRoutes
    DELETE(string, ...HandlerFunc) IRoutes
    PATCH(string, ...HandlerFunc) IRoutes
    PUT(string, ...HandlerFunc) IRoutes
    OPTIONS(string, ...HandlerFunc) IRoutes
    HEAD(string, ...HandlerFunc) IRoutes
    Match([]string, string, ...HandlerFunc) IRoutes

    StaticFile(string, string) IRoutes
    StaticFileFS(string, string, http.FileSystem) IRoutes
    Static(string, string) IRoutes
    StaticFS(string, http.FileSystem) IRoutes
}

Static X方法

路由接口中的最后这4个static x方法是用来处理静态文件的,他们的功能都一样,只是入参不一样而已。 他们的第一个参数relativePath就是静态资源的路由地址,后面的参数是不同类型的静态资源。 对于静态资源的处理,gin框架自动帮我们注册了2个请求方式,即 GET 用于静态资源的浏览查看, HEAD 用于获取静态资源的头信息 。

使用示例:r.Static("/static", "public/static")

方法参考

// Static serves files from the given file system root.
// Internally a http.FileServer is used, therefore http.NotFound is used instead
// of the Router's NotFound handler.
// To use the operating system's file system implementation,
// use :
//
//	router.Static("/static", "/var/www")
func (group *RouterGroup) Static(relativePath, root string) IRoutes {
	return group.StaticFS(relativePath, Dir(root, false))
}


// StaticFS works just like `Static()` but a custom `http.FileSystem` can be used instead.
// Gin by default uses: gin.Dir()
func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) IRoutes {
	if strings.Contains(relativePath, ":") || strings.Contains(relativePath, "*") {
		panic("URL parameters can not be used when serving a static folder")
	}
	handler := group.createStaticHandler(relativePath, fs)
	urlPattern := path.Join(relativePath, "/*filepath")

	// Register GET and HEAD handlers
	group.GET(urlPattern, handler)
	group.HEAD(urlPattern, handler)
	return group.returnObj()
}


func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem) HandlerFunc {
	absolutePath := group.calculateAbsolutePath(relativePath)
	fileServer := http.StripPrefix(absolutePath, http.FileServer(fs))

	return func(c *Context) {
		if _, noListing := fs.(*onlyFilesFS); noListing {
			c.Writer.WriteHeader(http.StatusNotFound)
		}

		file := c.Param("filepath")
		// Check if file exists and/or if we have permission to access it
		f, err := fs.Open(file)
		if err != nil {
			c.Writer.WriteHeader(http.StatusNotFound)
			c.handlers = group.engine.noRoute
			// Reset index
			c.index = -1
			return
		}
		f.Close()

		fileServer.ServeHTTP(c.Writer, c.Request)
	}
}

总结: gin框架的路由支持GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, CONNECT, TRACE这9种请求方式, 请求方式名称必须是大写, 这9种请求方式在gin内部都是通过handle方法来处理, gin框架中的路由处理函数和中间件的定义实际上就是定义一个入参类型为 *gin.Context  的函数或者方法。 gin在中间件中通过调用 gin.Context对象中的.Next()方法继续处理后续请求,通过调用 .Abort() 方法来中断后续请求,通过使用return语句立刻中断当前函数/方法的请求

要在gin框架中接收POST请求并在请求到达处理程序之前进行中间件处理,可以使用gin中间件功能。以下是一个示例中间件,它可以将POST请求的请求体中的JSON解析为一个结构体,并将其绑定到请求的上下文中: ```go func JsonMiddleware() gin.HandlerFunc { return func(c *gin.Context) { if c.Request.Method == "POST" { var data interface{} err := c.BindJSON(&data) if err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.Set("json_data", data) } c.Next() } } ``` 在这个中间件中,我们首先检查请求的HTTP方法是否为POST。如果是,我们尝试将请求体中的JSON解析为一个结构体。如果解析失败,我们返回一个HTTP 400错误响应,并终止请求。否则,我们将解析后的数据绑定到请求上下文的“json_data”键中,并继续处理请求。 要在gin应用程序中使用这个中间件,我们只需要在路由注册之前将其添加到应用程序的中间件链中: ```go router := gin.Default() router.Use(JsonMiddleware()) router.POST("/my-endpoint", func(c *gin.Context) { data := c.MustGet("json_data") // 处理请求数据 }) ``` 在这个示例中,我们使用gin.Default()创建一个新的路由器实例,并使用JsonMiddleware()函数添加一个中间件路由器的中间件链中。然后,我们注册一个POST处理程序,该处理程序使用c.MustGet("json_data")从请求上下文中获取JSON解析后的数据,并对数据进行处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值