golang路由拦截器

在golang中实现路由拦截有多种方法,比如一般来说框架都会实现拦截器或者中间件,本文是未采用web框架时一种拦截器的实现。
http.HandleFunc()的源码中可以看到第二个参数是一个func:

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
	DefaultServeMux.HandleFunc(pattern, handler)
}

所以这里可以定义一个map,键值分别是路由和处理函数:

type FilterHandle func(w http.ResponseWriter, r *http.Request) error

type Filter struct {
	filterMap map[string]FilterHandle
}

具体代码实现如下:

package common

import "net/http"

// 声明一个新的数据类型
type FilterHandle func(w http.ResponseWriter, r *http.Request) error

// 拦截器结构体
type Filter struct {
	filterMap map[string]FilterHandle
}

func NewFilter() *Filter {
	return &Filter{filterMap:make(map[string]FilterHandle)}
}

// 注册拦截器
func (f *Filter) RegisterFilterUri(uri string, handler FilterHandle) {
	f.filterMap[uri] = handler
}

// 根据Uri获取相应的handle
func (f *Filter) GetFilterHandle(uri string)FilterHandle {
	return f.filterMap[uri]
}

// 声明新的函数类型
type WebHandle func(w http.ResponseWriter, r *http.Request)


// 执行拦截器,返回函数类型
func (f *Filter) Handle(webHandle WebHandle) func(w http.ResponseWriter, r *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		for path, handle := range f.filterMap {
			if path == r.RequestURI {
				// 执行拦截业务逻辑
				err := handle(w, r)
				if err != nil {
					_, _ = w.Write([]byte(err.Error()))
					return
				}
				break
			}
		}
		webHandle(w, r)
	}
}

使用:

func main() {
	// 1.过滤器
	filter := common.NewFilter()
	// 注册拦截器
	filter.RegisterFilterUri("/check", Auth)
	filter.RegisterFilterUri("/generate", Generate)
	// 2.启动服务
	http.HandleFunc("/check", filter.Handle(Check))
	http.HandleFunc("/generate", filter.Handle(Check))
	_ = http.ListenAndServe(":8013", nil)
}

你可能感兴趣的:(Golang)