您的位置:首页 > 游戏 > 游戏 > 深圳物流公司招聘_国家市场监管总局小微企业名录库_淘宝运营主要做些什么_最好的搜索引擎

深圳物流公司招聘_国家市场监管总局小微企业名录库_淘宝运营主要做些什么_最好的搜索引擎

2025/2/25 2:29:13 来源:https://blog.csdn.net/Coffeemaker88/article/details/145767708  浏览:    关键词:深圳物流公司招聘_国家市场监管总局小微企业名录库_淘宝运营主要做些什么_最好的搜索引擎
深圳物流公司招聘_国家市场监管总局小微企业名录库_淘宝运营主要做些什么_最好的搜索引擎

Day1:HTTP 基础

今天的任务是:

  • 简单介绍net/http库以及http.Handler接口;
  • 搭建Gee框架的雏形,代码约 50 行;

标准库启动 Web 服务

Golang 内置了 net/http 库,封装了 HTTP 网络编程基础的接口,我们将要实现的 Gee 框架就是基于 net/http 的。接下来通过一个例子介绍 net/http 这个库如何使用:

package mainimport ("fmt""log""net/http"
)func main() {http.HandleFunc("/", indexHandler)http.HandleFunc("/hello", helloHandler)log.Fatal(http.ListenAndServe(":9999", nil))
}func indexHandler(w http.ResponseWriter, req *http.Request) {fmt.Fprintf(w, "URL.Path = %q\n", req.URL.Path)
}func helloHandler(w http.ResponseWriter, req *http.Request) {for k, v := range req.Header {fmt.Fprintf(w, "Header[%q] = %q\n", k, v)}
}

在上例当中我们设置了 2 个路由,分别是//hello,并将它们分别与 indexHandler 和 helloHandler 绑定,这两个函数会根据不同的 HTTP 请求调用不同的处理函数。访问 /,响应是 URL.Path = /。而 /hello 的响应则是 header 中的键值对信息。

main 函数的最后一行是用来启动 Web 服务的,第一个参数是地址,:9999代表在localhost:9999监听。第二个参数代表处理所有的 HTTP 请求的实例,nil 代表使用标准库中的实例处理。

第二个参数正是我们基于 net/http 标准库实现 Web 框架的入口。

实现 http.Handler 接口

package httptype Handler interface {ServeHTTP(w ResponseWriter, r *Request)
}func ListenAndServe(address string, h Handler) error

通过查看net/http的源码,发现Handler是一个接口,需要实现ServeHTTP方法,即:只要传入任何实现了 ServeHTTP 接口的实例,所有的 HTTP 请求就都将会交给这个传入的实例来处理了。现在让我们尝试一下:

package mainimport ("fmt""log""net/http"
)type Engine struct{}func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {switch req.URL.Path {case "/":fmt.Fprint(w, "URL.Path = %q\n", req.URL.Path)case "/hello":for k, v := range req.Header {fmt.Fprintf(w, "Header[%q] = %q\n", k, v)}default:fmt.Fprintf(w, "404 NOT FOUND: %s\n", req.URL)}
}func main() {engine := new(Engine)log.Fatal(http.ListenAndServe(":9999", engine))
}
  • 在上例当中,我们定义了一个空结构体Engine,它实现了方法ServeHTTP。这个方法有两个参数,第二个参数是 Request,该对象包含了该 HTTP 请求的所有的信息,比如请求地址、Header 和 Body 等信息;第一个参数是 ResponseWriter,利用 ResponseWriter 可以构造针对该请求的响应。
  • 在 main 当中,我们给 ListenAndServe 方法的第二个参数传入了刚才创建的 engine 实例。至此,我们已经走出了实现 Web 框架的第一步,即:将所有的 HTTP 请求转向了我们自己的处理逻辑。在实现 Engine 之前,我们只能通过调用 http.HandleFunc 才能实现路由和 Handler 映射,也就是只能针对具体的路由写处理逻辑。但是在实现 Engine 之后,我们拦截了所有的 HTTP 请求,拥有了统一的控制入口。在 Engine 的 ServeHTTP 方法当中,我们可以自由定义路由映射的规则,也可以统一添加一些处理逻辑,例如日志、异常处理等。

Gee 框架的雏形

文件的组织形式如下:
在这里插入图片描述

首先“搭建” main 函数:

package mainimport ("fmt""net/http"
)func main() {r := gee.New()r.GET("/", func(w http.ResponseWriter, req *http.Request) {fmt.Fprintf(w, "URL.Path = %q\n", req.URL.Path)})r.GET("/hello", func(w http.ResponseWriter, req *http.Request) {for k, v := range req.Header {fmt.Fprintf(w, "Header[%q] = %q\n", k, v)}})r.Run(":9999")
}

gee 在设计时其框架和 API 的设计均参考了 gin,因此上述逻辑与 gin 非常相似。使用 New() 创建 gee 的服务实例,使用 GET() 方法添加路由,最后使用 Run() 启动 Web 服务。目前路由仅支持静态路由。

gee.go

我们再来实现 gee.go

package geeimport ("fmt""net/http"
)// HandlerFunc defines the request handler used by gee
type HandlerFunc func(w http.ResponseWriter, r *http.Request)// Engine implements the interface of ServeHTTP
type Engine struct {router map[string]HandlerFunc
}// New is the constructor of gee.Engine
func New() *Engine {return &Engine{router: make(map[string]HandlerFunc)}
}// addRoute combines method and pattern together and then add method-pattern and handler to map
func (engine *Engine) addRoute(method, pattern string, handler HandlerFunc) {key := method + "-" + patternengine.router[key] = handler
}// GET defines the method to add GET request
func (engine *Engine) GET(pattern string, handler HandlerFunc) {engine.addRoute("GET", pattern, handler)
}// POST defines the method to add POST request
func (engine *Engine) POST(pattern string, handler HandlerFunc) {engine.addRoute("POST", pattern, handler)
}func (engine *Engine) Run(addr string) (err error) {return http.ListenAndServe(addr, engine)
}func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {key := req.Method + "-" + req.URL.Path // method + "-" + pattern, as key in Engine's mapif handler, ok := engine.router[key]; ok {handler(w, req)} else {fmt.Fprintf(w, "404 NOT FOUNT: %s\n", req.URL)}
}
  • 首先定义了类型HandlerFunc,它是提供给框架用户的,用来定义路由映射的处理方法。在Engine中,添加了一张路由映射表routerkey由请求方法和静态路由地址拼接而成,例如:GET-/GET-/helloPOST-/hello等。
  • 当用户调用(*Engine).GET()方法时,会将路由和处理方法注册到映射表 router 中。(*Engine).Run()是 ListenAndServe 的包装。
  • Engine 实现的 ServeHTTP 方法的作用就是,解析请求的路径,查找路由映射表,如果查到了,那么就执行注册的处理方法,否则返回 404 NOT FOUND。

至此,Gee 框架的原型已经完成了,逻辑还是非常的清晰和易于理解的。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com