1. 程式人生 > 其它 >gin框架路由組原始碼剖析

gin框架路由組原始碼剖析

package main

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

func main() {
	r := gin.New()

	// 1. 新增中介軟體
	r.Use(gin.Logger(), gin.Recovery())

	// 2. 405支援
	r.HandleMethodNotAllowed = true

	// 3. 自定義404頁面
	r.NoRoute(myNoRoute)
	// 4. 自定義405頁面
	r.NoMethod(myNoMethod)  // 405頁面需要搭配405支援一起使用

	// 5. 建立路由組
	user := r.Group("user")

	// 6. 獲取路由組的基本路徑
	fmt.Println(user.BasePath())

	// 7. 列印路由組的處理程程式鏈
	for _, handler := range user.Handlers{
		fmt.Println(runtime.FuncForPC(reflect.ValueOf(handler).Pointer()).Name())
	}

	// 8. 註冊路由
	user.Handle("GET", "/register", func(context *gin.Context) {
		context.String(200, "這是註冊頁面")
	})

	// 9. 大殺器,不建議使用(註冊一個支援所有方法的路由)
	// Any 註冊一個匹配所有 HTTP 方法的路由。 GET、POST、PUT、PATCH、HEAD、OPTIONS、DELETE、CONNECT、TRACE
	user.Any("/any", func(context *gin.Context) {
		context.String(200, "這是一個支援任何方法的路由")
	})

	// 10. 註冊單個檔案路由
	//user.StaticFile("/01.png", "http_server/file/01.png")

	// 11. 註冊檔案目錄路由, 不提供檔案列表
	//user.Static("/static", "http_server/file/")

	// 12. 註冊檔案目錄路由,可以提供檔案列表, true代表提供檔案列表
	user.StaticFS("/static", gin.Dir("http_server/file/", true))

	user.GET("/login/:name", login)

	_ = r.Run()

}

func myNoMethod(context *gin.Context) {
	context.String(http.StatusMethodNotAllowed, "您請求的方法不允許")
}

func myNoRoute(context *gin.Context) {
	context.String(http.StatusNotFound, "您要訪問的頁面不存在")
}

func login(context *gin.Context) {
	context.String(200, "OK")
}

/*
routegroup.go中幾個非常重要的方法

方法1:合併處理程式鏈
func (group *RouterGroup) combineHandlers(handlers HandlersChain) HandlersChain {
	finalSize := len(group.Handlers) + len(handlers)
	if finalSize >= int(abortIndex) {  // abortIndex = 32
		panic("too many handlers")
	}
	mergedHandlers := make(HandlersChain, finalSize)
	copy(mergedHandlers, group.Handlers)
	copy(mergedHandlers[len(group.Handlers):], handlers)
	return mergedHandlers
}

方法2:拼接絕對路徑
func (group *RouterGroup) calculateAbsolutePath(relativePath string) string {
	return joinPaths(group.basePath, relativePath)
}

方法3:返回Engine或RouterGroup
func (group *RouterGroup) returnObj() IRoutes {
	if group.root {
		return group.engine
	}
	return group
}

 */