golang中自定义实现支持正则表达式的http请求路由器


package main

import (
	"fmt"
	"net"
	"net/http"
	"regexp"
)

// http请求的路由,多路复用器
var serveMux = new(http.ServeMux)

func main() {
	// 所有请求都走此匹配
	serveMux.HandleFunc("/", Route)
	listen, _ := net.Listen("tcp", ":8000")
	fmt.Println("服务已启动:", "127.0.0.1:8000")
	http.Serve(listen, serveMux)
}

type routeInfo struct {
	pattern string
	handler http.Handler
}

var routePath = []routeInfo{
	{pattern: "^/index$", handler: index()},  // 匹配:/index
	{pattern: "^/hello/?$", handler: hello()},  // 匹配:/hello 或者 /hello/
}

func Route(w http.ResponseWriter, r *http.Request) {
	isFound := false
	for _, route := range routePath{
		// 这里循环匹配path,先添加的先匹配
		re, err := regexp.Compile(route.pattern)
		if err != nil {
			continue
		}
		// MatchString 报告字符串 s 是否包含正则表达式 re 的任何匹配项。
		if re.MatchString(r.URL.Path){
			isFound = true
			// 将接口类型转换为具体的函数类型,在进行调用,这源码中的用法真实牛逼
			route.handler.(http.HandlerFunc)(w, r)
			return
		}
	}
	if !isFound{
		fmt.Fprint(w, "404 Page Not Found")
	}
}

func index() http.Handler {
	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		_, _ = fmt.Fprint(writer, "这是首页")
	})
}
func hello() http.Handler {
	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		_, _ = fmt.Fprint(writer, "这是hello页面")
	})
}