Golang中HttpRouter路由的使用详解

作者:技术颜良 时间:2024-04-30 10:04:23 

httprouter

httprouter 是一个高性能、可扩展的HTTP路由,上面我们列举的net/http默认路由的不足,都被httprouter 实现,我们先用一个例子,认识下 httprouter 这个强大的 HTTP 路由。

安装:

go get -u github.com/julienschmidt/httprouter

在这个例子中,首先通过httprouter.New()生成了一个*Router路由指针,然后使用GET方法注册一个适配/路径的Index函数,最后*Router作为参数传给ListenAndServe函数启动HTTP服务即可。

package main

import (
   "log"
   "net/http"

"github.com/julienschmidt/httprouter"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
   w.Write([]byte("Index"))
}

func main() {
   router := httprouter.New()
   router.GET("/", Index)
   log.Fatal(http.ListenAndServe(":8080", router))
}

httprouter 为所有的HTTP Method 提供了快捷的使用方式,只需要调用对应的方法即可。

func (r *Router) GET(path string, handle Handle) {
   r.Handle("GET", path, handle)
}
func (r *Router) HEAD(path string, handle Handle) {
   r.Handle("HEAD", path, handle)
}
func (r *Router) OPTIONS(path string, handle Handle) {
   r.Handle("OPTIONS", path, handle)
}
func (r *Router) POST(path string, handle Handle) {
   r.Handle("POST", path, handle)
}
func (r *Router) PUT(path string, handle Handle) {
   r.Handle("PUT", path, handle)
}
func (r *Router) PATCH(path string, handle Handle) {
   r.Handle("PATCH", path, handle)
}
func (r *Router) DELETE(path string, handle Handle) {
   r.Handle("DELETE", path, handle)
}

现代的API,基本上都是Restful API,httprouter提供的命名参数的支持,可以很方便的帮助我们开发Restful API。比如我们设计的API/user/flysnow,这这样一个URL,可以查看flysnow这个用户的信息,如果要查看其他用户的,比如zhangsan,我们只需要访问API/user/zhangsan即可。

URL包括两种匹配模式:/user/:name精确匹配、/user/*name匹配所有的模式。

package main

import (
 "github.com/julienschmidt/httprouter"
 "net/http"
 "log"
 "fmt"
)

func main()  {
 router:=httprouter.New()
 router.GET("/MainData", func (w http.ResponseWriter,r *http.Request,_ httprouter.Params)  {
   w.Write([]byte("default get"))
 })
 router.POST("/MainData",func (w http.ResponseWriter,r *http.Request,_ httprouter.Params)  {
   w.Write([]byte("default post"))
 })
 //精确匹配
 router.GET("/user/name",func (w http.ResponseWriter,r *http.Request,p httprouter.Params)  {
   w.Write([]byte("user name:"+p.ByName("name")))
 })
 //匹配所有
 router.GET("/employee/*name",func (w http.ResponseWriter,r *http.Request,p httprouter.Params)  {
   w.Write([]byte("employee name:"+p.ByName("name")))
 })
 http.ListenAndServe(":8081", router)
}

Handler处理链处理不同二级域名

package main

import (
   "fmt"
   "log"
   "net/http"

"github.com/julienschmidt/httprouter"
)

type HostMap map[string]http.Handler

func (hs HostMap) ServeHTTP(w http.ResponseWriter, r *http.Request) {
   fmt.Println("222")
   //根据域名获取对应的Handler路由,然后调用处理(分发机制)
   if handler := hs[r.Host]; handler != nil {
       handler.ServeHTTP(w, r)
   } else {
       http.Error(w, "Forbidden", 403)
   }
}

func main() {
   userRouter := httprouter.New()
   userRouter.GET("/", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
       w.Write([]byte("play"))
   })

dataRouter := httprouter.New()
   dataRouter.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
       w.Write([]byte("tool"))
   })

//分别用于处理不同的二级域名
   hs := make(HostMap)
   hs["user.localhost:12345"] = userRouter
   hs["data.localhost:12345"] = dataRouter

log.Fatal(http.ListenAndServe(":12345", hs))
}

httprouter提供了很方便的静态文件服务,可以把一个目录托管在服务器上,以供访问。

router.ServeFiles("/static/*filepath",http.Dir("./"))

使用ServeFiles需要注意的是,第一个参数路径,必须要以/*filepath,因为要获取我们要访问的路径信息。

func (r *Router) ServeFiles(path string, root http.FileSystem) {
   if len(path) < 10 || path[len(path)-10:] != "/*filepath" {
       panic("path must end with /*filepath in path '" + path + "'")
   }
   fileServer := http.FileServer(root)
   r.GET(path, func(w http.ResponseWriter, req *http.Request, ps Params) {
       req.URL.Path = ps.ByName("filepath")
       fileServer.ServeHTTP(w, req)
   })
}

例子:

package main
import (
   "log"
   "net/http"
   "github.com/julienschmidt/httprouter"
)
func main() {
   router := httprouter.New()
 //访问静态文件
   router.ServeFiles("/static/*filepath", http.Dir("./files"))
   log.Fatal(http.ListenAndServe(":8080", router))
}

httprouter 异常捕获,httprouter允许使用者,设置PanicHandler用于处理HTTP请求中发生的panic。

package main
import (
   "fmt"
   "log"
   "net/http"
   "github.com/julienschmidt/httprouter"
)
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
   panic("error")
}
func main() {
   router := httprouter.New()
   router.GET("/", Index)
 //捕获异常
   router.PanicHandler = func(w http.ResponseWriter, r *http.Request, v interface{}) {
       w.WriteHeader(http.StatusInternalServerError)
       fmt.Fprintf(w, "error:%s", v)
   }
   log.Fatal(http.ListenAndServe(":8080", router))
}

httprouter还有不少有用的小功能,比如对404进行处理,我们通过设置Router.NotFound来实现,我们看看Router这个结构体的配置,可以发现更多有用的功能。

type Router struct {
   //是否通过重定向,给路径自定加斜杠
   RedirectTrailingSlash bool
   //是否通过重定向,自动修复路径,比如双斜杠等自动修复为单斜杠
   RedirectFixedPath bool
   //是否检测当前请求的方法被允许
   HandleMethodNotAllowed bool
   //是否自定答复OPTION请求
   HandleOPTIONS bool
   //404默认处理
   NotFound http.Handler
   //不被允许的方法默认处理
   MethodNotAllowed http.Handler
   //异常统一处理
   PanicHandler func(http.ResponseWriter, *http.Request, interface{})
}

来源:https://www.cnblogs.com/cheyunhua/p/15545261.html

标签:Go,HttpRouter
0
投稿

猜你喜欢

  • JS中定位 position 的使用实例代码

    2024-05-03 15:05:09
  • JetBrains(IEDA、CLion、Pycharm) 学生获得免费使用资格

    2022-02-21 09:25:35
  • 新版php study根目录下文件夹无法显示的图文解决方法

    2023-11-15 00:44:29
  • 在python中实现求输出1-3+5-7+9-......101的和

    2022-10-08 16:33:14
  • python3处理word文档实例分析

    2023-01-06 23:21:13
  • 请正确认识MySQL对服务器端光标的限制

    2008-12-17 14:58:00
  • idea创建springMVC框架和配置小文件的教程图解

    2021-04-03 15:22:54
  • asp自动生成javascript检验函数

    2009-01-21 19:40:00
  • python没有gpu,如何改用cpu跑代码

    2022-09-26 00:24:49
  • Pycharm 2020年最新激活码(亲测有效)

    2023-07-24 00:42:14
  • ASP 支持中文的len(),left(),right()的函数代码

    2011-03-03 10:59:00
  • 分享javascript、jquery实用代码段

    2024-04-17 10:02:54
  • 一个函数解决SQLServer中bigint 转 int带符号时报错问题

    2024-01-19 23:26:36
  • mysql下mysqladmin日常管理命令总结(必看篇)

    2024-01-16 23:35:55
  • SQL Server跟踪数据实现索引优化向导

    2009-02-13 17:14:00
  • 一篇文章介绍redux、react-redux、redux-saga总结

    2023-08-22 16:56:32
  • Pytorch反向求导更新网络参数的方法

    2021-02-07 11:48:52
  • Go语言切片常考的面试真题解析

    2024-04-30 10:07:16
  • Python3中configparser模块读写ini文件并解析配置的用法详解

    2022-11-02 12:11:14
  • python批量生成本地ip地址的方法

    2021-10-25 16:20:38
  • asp之家 网络编程 m.aspxhome.com