方案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"))
}