当前位置: 首页 > news >正文

【Go】 HTTP编程3-路由httprouter

 HttpRouter

httprouter

  • httprouter是第三方的库,不是go的标准库,使用命令 go get -u github.com/julienschmidt/httprouter ,下载该模块,-u表示如果已经下载但更新到最新版本
  • Router 实现了http.Handler接口,为各种 request method (get/post等) 提供了便捷的路由方式,之前是根据路径区分,现在可以根据方法区分
  • 支持restful请求方式,什么是restful ,原来参数通过?参数名=参数值 进行参数传递, 现在可以把参数放到路径中 ,但是需要提前约定好每一集路径代表什么参数
  • 支持ServeFiles访问静态文件,现实中 ,服务端多的是需要返回HTML页面,html页面怎么返回,在第三方包中可以把静态文件返回给客户端 
  • 可以自定义处理panic的方法

HttpRouter 是一个轻量级高性能的 HTTP 请求路由器(也称为多路复用器或简称 mux)用于 Go 语言。

与 Go 的 net/http 包中默认的 mux 不同,该路由器支持路由模式中的变量,并且匹配请求方法。它还具有更好的扩展性。

该路由器经过优化,具有高性能和小内存占用。即使在非常长的路径和大量路由的情况下,它也能很好地扩展。采用了一种压缩动态字典树(基数树)结构以实现高效匹配。

特点

仅显式匹配:与其他路由器(如 http.ServeMux)不同,请求的 URL 路径可能与多个模式匹配。因此它们具有一些尴尬的模式优先规则,如最长匹配或首次注册,首次匹配。通过该路由器的设计,一个请求只能匹配一个或零个路由。因此,也不会出现意外的匹配,这使其非常适合 SEO 并提高了用户体验。

不必再关心尾部斜杠:选择你喜欢的 URL 样式,如果缺少尾部斜杠或有一个额外的,路由器会自动将客户端重定向。当然,它只会这样做,如果新路径有一个处理程序。如果你不喜欢,可以关闭此行为。

路径自动修正:除了在不增加额外成本的情况下检测缺少或额外的尾部斜杠外,路由器还可以修复错误的情况并删除多余的路径元素(如 ../ 或 //)。是否有使用大写锁定键的用户?HttpRouter 可以通过进行大小写不敏感的查找并将其重定向到正确的 URL 来帮助他。

路由模式中的参数:停止解析请求的 URL 路径,只需给路径段一个名称,路由器就会将动态值传递给您。由于路由器的设计,路径参数非常便宜。

零垃圾:匹配和分派过程不会生成任何垃圾字节。唯一的堆分配是构建路径参数的键值对切片以及构建新的上下文和请求对象(后者仅在标准 Handler/HandlerFunc API 中)。在 3 参数 API 中,如果请求路径不包含任何参数,则不需要进行任何堆分配。

最佳性能:基准测试说话。请参阅下面有关实现的技术细节。

不再有服务器崩溃:您可以设置 Panic 处理程序来处理在处理 HTTP 请求期间发生的 panic。然后路由器会恢复并让 PanicHandler 记录发生的情况并提供一个友好的错误页面。

非常适合 API:路由器设计鼓励构建合理的、分层的 RESTful API。此外,它还内置了对 OPTIONS 请求和 405 Method Not Allowed 回复的本地支持。

当然,您也可以设置自定义的 NotFound 和 MethodNotAllowed 处理程序,并提供静态文件服务。

使用

下载库

$ go get github.com/julienschmidt/httprouter

package mainimport ("fmt""github.com/julienschmidt/httprouter""net/http"
)// 接受的参数 w http.ResponseWriter,r *http.Request, params httprouter.Params
func get(w http.ResponseWriter,r *http.Request, params httprouter.Params)  {// 打印请求方法fmt.Printf("request method:%s",r.Method)// 打印请求体fmt.Println("request Body:")//io.Copy(os.Stdout,r.Body)// 打印请求头fmt.Println("request Header:")for k,v := range r.Header {fmt.Printf("%s = %s\n", k,v)}// 返回客户端的内容,下面两种方式等价fmt.Fprintf(w,"hello boy!")//w.Write([]byte("hello boy!"))}func panicTest(w http.ResponseWriter,r *http.Request, params httprouter.Params)  {// 打印请求方法fmt.Printf("request method:%s",r.Method)// 打印请求体fmt.Println("request Body:")//io.Copy(os.Stdout,r.Body)// 打印请求头fmt.Println("request Header:")for k,v := range r.Header {fmt.Printf("%s = %s\n", k,v)}// 返回客户端的内容,下面两种方式等价fmt.Fprintf(w,"hello boy!")//w.Write([]byte("hello boy!"))// 故意制造一个数组越界 panicarr := [5]int{1, 2, 3, 4, 5}for i := 0; i < 10; i++ {fmt.Println(arr[i])}}func post(w http.ResponseWriter,r *http.Request,params httprouter.Params)  {// 打印请求方法fmt.Printf("request method:%s\n",r.Method)// 打印请求体fmt.Println("request Body:")//io.Copy(os.Stdout,r.Body)// 打印请求头fmt.Println("request Header:")for k,v := range r.Header {fmt.Printf("%s = %s\n", k,v)}// 返回客户端的内容,下面两种方式等价fmt.Fprintf(w,"hello girl!")//w.Write([]byte("hello boy!"))
}func main ()  {router := httprouter.New()// GET is a shortcut for router.Handle(http.MethodGet, path, handle)// GET 是  router.Handle(http.MethodGet, path, handle)  简写// GET 接收两个参数,第一个参数 字符串类型 代表请求路径,第二个参数是函数类型  func(http.ResponseWriter, *http.Request, Params),代表处理函数,所以我们在写处理函数的时候,需要满足这个类型router.GET("/",get)router.GET("/panictest",panicTest)// restful 风格router.GET("/user/:name/:type/*addr", func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {fmt.Printf("name= %s,type=%s addr = %s",params.ByName("name"),params.ByName("type"),params.ByName("addr"))msg :=fmt.Sprintf("name= %s,type=%s addr = %s",params.ByName("name"),params.ByName("type"),params.ByName("addr"))writer.Write([]byte(msg))})// ServerFiles - 返回静态文件 ,访问 http://127.0.0.1:8888/file/a.html路径 ,会去目录 ./static 找 a.html文件router.ServeFiles("/file/*filepath",http.Dir("./static"))router.PanicHandler = func(writer http.ResponseWriter, request *http.Request,i interface{}) {fmt.Fprintf(writer,"服务器正在维护:%s,请稍后再试",i)}//  ListenAndServe 第一个参数是地址,第二个参数是 实现 handler类型的函数http.ListenAndServe(":8888",router)}

参考资料

GitHub

GitHub - julienschmidt/httprouter: A high performance HTTP request router that scales well

文档

httprouter package - github.com/julienschmidt/httprouter - Go Packages

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • VisionPro二次开发学习笔记12-使用CogToolGroup控件进行图像检测
  • 五. TensorRT API的基本使用-custom-trt-plugin
  • js入门经典学习小结
  • 【Python】PyWebIO 初体验:用 Python 写网页
  • 006 | 资本资产定价模型 (CAPM)
  • MySQL学习(20):InnoDB引擎逻辑架构、物理架构
  • Unity入门2——编辑器常用功能
  • 投资 - 什么叫有资金托底
  • 当node节点kubectl 命令无法连接到 Kubernetes API 服务器
  • k8s创建secret并在container中获取secret
  • Spring框架面试总结
  • java最强本地缓存-Caffeine
  • 「数组」随机快速选择 / LeetCode LCR 076(C++)
  • VMWare虚拟机磁盘扩容
  • 【langchain学习】使用LangChain创建具有上下文感知的问答系统
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • es6
  • express + mock 让前后台并行开发
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Koa2 之文件上传下载
  • PAT A1120
  • PhantomJS 安装
  • Sass Day-01
  • Swoft 源码剖析 - 代码自动更新机制
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 复习Javascript专题(四):js中的深浅拷贝
  • 简单实现一个textarea自适应高度
  • 面试总结JavaScript篇
  • 浅谈Golang中select的用法
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • No resource identifier found for attribute,RxJava之zip操作符
  • HanLP分词命名实体提取详解
  • kubernetes资源对象--ingress
  • Spring Batch JSON 支持
  • 数据可视化之下发图实践
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​queue --- 一个同步的队列类​
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • ‌前端列表展示1000条大量数据时,后端通常需要进行一定的处理。‌
  • #includecmath
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (1)Hilt的基本概念和使用
  • (二十三)Flask之高频面试点
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (排序详解之 堆排序)
  • (十三)MipMap
  • (贪心) LeetCode 45. 跳跃游戏 II
  • (学习日记)2024.01.19
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • .form文件_一篇文章学会文件上传