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

方案1:使用ServeMux

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页面")
	})
}

方案2:直接使用

package main

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

func main() {
	l, _ := net.Listen("tcp", "127.0.0.1:8080")
	_ = http.Serve(l, route())
}

type routeInfo struct {
	path string
	handler http.HandlerFunc
}

var routePath = []routeInfo{
	{path: "^/index/\\d+$", handler: index},  // \d: 匹配数字
	{path: "^/home/\\w+$", handler: home},  // \w:匹配字母、数字、下划线
}

func route() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request){
		for _, route := range routePath{
			ok, err := regexp.Match(route.path, []byte(r.URL.Path))
			if err != nil {
				fmt.Println(err.Error())
			}
			if ok{
				route.handler(w, r)
				return
			}
		}
		_, _ = w.Write([]byte("404 not found"))
	}
}

func index(w http.ResponseWriter, r *http.Request) {
	_, _ = w.Write([]byte("index"))
}

func home(w http.ResponseWriter, r *http.Request) {
	_, _ = w.Write([]byte("home"))
}

posted @ 2022-05-10 14:32  专职  阅读(500)  评论(0编辑  收藏  举报