studygolang源码阅读小结 <四>

whispermemory · · 4476 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

##http与 router## 先看http 提供的强大简洁服务器端的功能 - HTTP响应模块 func ListenAndServe(addr string, handler Handler) error 这个方法就处理了所有的http请求。第二个参数如下 type Handler interface { ServeHTTP(ResponseWriter, *Request) } 也就是实现了该接口的结构,均能够对http请求作出相应。看这个方法的参数大致就能猜出,这个方法是让使用者自己往RewponseWriter中写http header 以及http data。 type ResponseWriter interface { Header() Header Write([]byte) (int, error) WriteHeader(int) } 当第二个参数为空的时候,默认由系统的对象http.DefaultServeMux进行处理,看结构体 type ServeMux struct { // contains filtered or unexported fields } 这个对象会对Listen到的http请求进行路由。让不同的Handler进行处理。因此在Listen之前需要对ServeMux注册Handler。调用下面方法即可 func Handle(pattern string, handler Handler) func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) 第一个方法的第二个参数是一个Handle类型接口,第二个方法是直接提供了一个Handle接口需要的接口方法。总之需要一个实现serveHTTP的结构体。而这个结构体则是studygolang很关键的一个模块。即router - Router Router这个结构体在studygolang中最重要的作用就是handler的路由,看ServeHttp提供的路由功能代码: func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { // Clean path to canonical form and redirect. if p := cleanPath(req.URL.Path); p != req.URL.Path { w.Header().Set("Location", p) w.WriteHeader(http.StatusMovedPermanently) return } var match RouteMatch var handler http.Handler if r.Match(req, &match) { handler = match.Handler setVars(req, match.Vars) setCurrentRoute(req, match.Route) } if handler == nil { if r.NotFoundHandler == nil { r.NotFoundHandler = http.NotFoundHandler() } handler = r.NotFoundHandler } defer context.Clear(req) handler.ServeHTTP(w, req) } 在Router内嵌Route指针数组,通过Route来跟request进行匹配。而Route内部则存储http.Handler。如果匹配成功则,使用该Route内的Handler对请求进行响应。 type Route struct { // Parent where the route was registered (a Router). parent parentRoute // Request handler for the route. handler http.Handler // List of matchers. matchers []matcher // Manager for the variables from host and path. regexp *routeRegexpGroup // If true, when the path pattern is "/path/", accessing "/path" will // redirect to the former and vice versa. strictSlash bool // If true, this route never matches: it is only used to build URLs. buildOnly bool // The name used to build URLs. name string // Error resulted from building a route. err error // 过滤器链 FilterChain *FilterChain } 通过该结构体的源码可以明白Route跟Path之间的关系是一一对应的,在每一个Route里面存储有一个Path。Route跟handle也是一一对应的,但是一个Route里面是可以有多个Filter的。首先是request 跟 Route之间的匹配。只要拿到request的URI就可以获取相匹配的Path。其次是Filter的调用与Handler的调用关系,就是Filter模块。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4476 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传