学习Go语言Web框架Gee总结--http.Handler
- http-base/go.mod
- http-base/main.go
- http-base/gee/gee.go
- http-base/gee/go.mod
网站学习来源:Gee
代码目录结构:
http-base/go.mod
//指定当前模块的名称为 "example"
module example
//指定当前模块所需的 Go 版本为 1.21.5
go 1.21.5
//表示当前模块需要一个名为 "gee" 的模块,版本为 v0.0.0
require gee v0.0.0
//一个替换指令,它告诉编译器在构建过程中使用本地文件系统中的 gee 模块,而不是从远程仓库获取
replace gee => ./gee
go.mod 提供了module、require、replace、exclude四个命令
-
module语句指定包的名字(路径)
-
require语句指定的依赖项模块
-
replace语句可以替换依赖项模块
-
exclude语句可以忽略依赖项模块
http-base/main.go
package main
//"fmt" 包用于格式化输入输出
//"gee" 是自定义的 Web 框架
//"net/http" 是 Go 标准库中用于 HTTP 编程的包
import (
"fmt"
"gee"
"net/http"
)
func main() {
//创建一个 gee 实例
r := gee.New()
//使用 r.GET 注册了两个路由,分别处理根路径 "/" 和 "/hello" 的 GET 请求
//每个路由都有一个处理函数,用于处理对应的请求
//
r.GET("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
})
r.GET("/hello", func(w http.ResponseWriter, r *http.Request) {
for k, v := range r.Header {
fmt.Fprintf(w, "Header[%q] = %q\n", k, v)
}
})
//启动 HTTP 服务器,监听在 9999 端口上
r.Run(":9999")
}
效果如下:
其中fmt.Fprintf 函数是 fmt 包中的一个格式化输出函数,它的作用是将格式化的内容写入到指定的输出流(io.Writer 接口类型)中
函数签名为:
//其中type any = interface{}
func Fprintf(w io.Writer, format string, a ...any) (n int, err error)
所以上面的代码将会把 "URL.Path = " 和 r.URL.Path 的值按照指定的格式写入到 w 所指定的输出流中,这里的 w 是一个 http.ResponseWriter,用于将内容写入 HTTP 响应
http-base/gee/gee.go
//定义名为 gee 的包
package gee
import (
"fmt"
"net/http"
)
//定义类型 HandlerFunc,它是一个函数类型,接受一个 http.ResponseWriter和一个 *http.Request 作为参数,用于定义路由映射的处理方法
type HandlerFunc func(w http.ResponseWriter, r *http.Request)
//定义结构体 Engine,有一个名为 router 的字段,类型为 map[string]HandlerFunc,用于存储路由信息
type Engine struct {
router map[string]HandlerFunc
}
//用于创建一个新的 Engine 实例,它返回一个指向 Engine 实例的指针,并初始化了 router 字段为一个空的 map
func New() *Engine {
return &Engine{
router: make(map[string]HandlerFunc),
}
}
//接受三个参数:HTTP 方法名、URL 模式和处理函数
//Engine中路由映射表router,key 由请求方法和静态路由地址构成,例如GET-/、GET-/hello、POST-/hello
//映射到不同的处理方法(Handler)
func (engine *Engine) addRoute(method string, pattern string, handler HandlerFunc) {
key := method + "-" + pattern
engine.router[key] = handler
}
func (engine *Engine) GET(pattern string, handler HandlerFunc) {
engine.addRoute("GET", pattern, handler)
}
func (engine *Engine) POST(pattern string, handler HandlerFunc) {
engine.addRoute("POST", pattern, handler)
}
//是对 ListenAndServe 的包装
func (engine *Engine) Run(addr string) (err error) {
return http.ListenAndServe(addr, engine)
}
//ServeHTTP 方法实现了 http.Handler 接口,用于统一处理 HTTP 请求
//解析请求的路径,查找路由映射表,如果查到,就执行注册的处理方法。如果查不到,就返回 404 NOT FOUND
func (engine *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
key := r.Method + "-" + r.URL.Path
if handler, ok := engine.router[key]; ok {
handler(w, r)
} else {
fmt.Fprintf(w, "404 NOT FOUND", r.URL)
}
}
http-base/gee/go.mod
module gee
go 1.21.5