Golang中的路由使用详解

  

之前有篇文章比较浅显的分析了一下golang的服务器如何实现,还有<代码>处理程序,DefaultServeMux, HandlerFunc>   

我们现在已经明白了<代码> DefaultServeMux> 模式和<代码>处理程序代码的地方,我们称其为路由,那么我们可能会想,既然golang能够实现这个路由,我们能否也模仿一个呢?

  

首先我们需要一个能够保存客户端的请求的一个容器(路由)。

  

<>强创建路由结构体
  

        CopyRouter struct类型{   路由器map [string] [string] http.HandlerFunc地图   }   之前      

在这里我们创建了一个像DefaultServeMux的路由。

  

<强>客户端请求存入路由
  

        func (c * CopyRouter) HandleFunc(方法、模式字符串处理http.HandlerFunc) {   如果方法==" {   恐慌(“方法不能空!”)   }      如果模式==" {   恐慌(”模式不能空!”)   }      如果_,好的:=c.router[方法](模式);好{   恐慌(“模式存在!”)   }      如果c。路由器==nil {   c。路由器=使(map [string] map [string] http.HandlerFunc)   }      如果c。路由器[方法]==nil {   c。路由器[方法]=使(map [string] http.HandlerFunc)   }   c。路由器[方法][模式]=处理   }      之前      

这里我们模仿源码中的<代码> ServeMux>   

<>强实现处理器接口
  

        func (c * CopyRouter) ServeHTTP http (w。ResponseWriter r * http.Request) {   好的,如果f:=c.router [r.Method] [r.URL.String ());好{   f。ServeHTTP (w, r)   }   }   之前      

在这里为什么要实现这个处理器接口,因为我们发现在ListenAndServe方法中,最后会调用<代码> h。ServeHTTP (w, r), 那么我们就只需要让我们定义的路由实现<代码>处理程序代码接口就可以了。

  

<强>获取一个路由
  

        * CopyRouter func NewRouter () {   返回新(CopyRouter)   }   之前      

到这里,我们自己定义的路由就完成了,我们来看看使用方法。

        func sayHi http (w。ResponseWriter r * http.Request) {   fmt.Fprint (w,“嗨”)   }      函数main () {   copyRouter:=copyrouter.NewRouter ()   copyRouter。HandleFunc(“获得”、“/sayHi”sayHi)   log.Fatal (http。ListenAndServe (“localhost: 8080”, copyRouter))   }      之前      

这样就完成了一个高仿版的自定义路由,是不是和golang提供给我们的<代码> ServeMux>   

现在再看看,我们的主要函数里面的代码不是很美观,每一次都要写得到或者发布方法,那么我们能否提供一个比较美观的方式呢?可以,那么我们再封装一下。

        func (c * CopyRouter)得到(模式字符串处理程序http.HandlerFunc) {   c。HandleFunc(“得到”模式,处理程序)   }      func (c * CopyRouter)帖子(模式字符串处理程序http.HandlerFunc) {   c。HandleFunc (“POST”模式,处理程序)   }      …      之前      

然后再修改一下调用方式。

        copyRouter.GET (“/sayHi”, sayHi)      

现在看起来是不是就美观很多了吗?是的,很多web框架也是这样,为什么用起来就感觉很流畅,因为这些大神们就是站在我们开发者的角度来考虑问题,提供了很方便的一些用法,封装的很完善。

  

再考虑一下,我们这个自定义的路由还能做些什么,如果我们要记录每一次的访问请求,该如何处理呢?也很简单,我们只需要将逻辑写在<代码> ServeHTTP 方法中就可以了,稍微修改一下我们的代码。

        func (c * CopyRouter) ServeHTTP http (w。ResponseWriter r * http.Request) {   好的,如果f:=c.router [r.Method] [r.URL.String ());好{   func(处理程序http.Handler) {   开始:=time.Now ()   日志。Printf("请求(% s)开始时间为:% v \ n”, r.URL.String(),开始)   f。ServeHTTP (w, r)   日志。Printf("请求(% s)完成时间为:% v \ n”, r.URL.String (), time.Since(开始)   }(f)   }   }   

Golang中的路由使用详解