ServeMux简介

ServeMux扮演的角色是Multiplexer,它用来将将请求根据url路由给已注册的handler。如下图:

上图中为3个路径注册了handler,一个是"/",另外两个是"/hello"和"/world"。这表示访问http://hostname/hello时,multiplexer会调用上图中对应的第二个handler,当访问http://hostname/world时,multiplexer会调用上图中对应的第三个handler,当不是这两个路径时,将调用第一个绑定在"/"上的handler。

注意,go的mux路由请求时,handler绑定的路径是否带尾随"/"是不一样的。带上尾随"/",表示此路径以及此路径下的子路径,都会调用注册在此路径上的handler

例如,当请求uri为"/hello/abc"的时候,不会调用"/hello"对应的handler,而是调用"/"对应的handler。只有注册handler的路径为"/hello/"时,uri为"/hello/abc"才会调用此handler。

实际上,当注册handler的路径带上尾随斜"/"时,在发起此路径的请求时,会通过301重定向的方式自动补齐这个尾随斜线,让浏览器发起第二次请求。例如,下面是注册handler的路径:

http.Handle("/hello/", &myHandler)

发起http://hostname/hello的请求时,会自动补齐为http://hostname/hello/,然后浏览器自动发起第二次请求。

ServeMux的匹配规则

ServeMux对每次流入的http请求的URL进行模式(pattern)匹配,然后调用注册在此pattern上的handler来处理这个请求。

Pattern部分可以定义为匹配host的模式。如果pattern以"/"开头,表示匹配URL的路径部分,如果不以"/"开头,表示从host开始匹配。

匹配时选择匹配匹配度最高(长匹配优先于短匹配)。例如为"/images/"注册了handler1,"/images/thumbnails/"注册了handler2,如果请求的URL路径部分为"/images/thumbnails/",将会调用handler2处理这个请求,如果请求的URL路径部分为"/images/foo/",将调用handler1处理。

注意,注册在"/"上的pattern会在其它模式匹配不上时被选中,因为所有请求都可以匹配这个pattern,只不过能匹配到的长度最短。

如果pattern带上了尾随斜线"/",ServeMux将会对请求不带尾随斜线的URL进行301重定向。例如,在"/images/"模式上注册了一个handler,当请求的URL路径为"/images"时,将自动重定向为"/images/"。除非再单独为"/images"模式注册一个handler。

如果为"/images"注册了handler,当请求URL路径为"/images/"时,将无法匹配该模式。

ServeMux详细解释

看看net/http/server.go文件中ServeMux的结构:

type ServeMux struct {mu    sync.RWMutexm     map[string]muxEntryhosts bool // whether any patterns contain hostnames
}type muxEntry struct {h       Handlerpattern string
}

结构看上去很简单。一个字段mu是RWMutex,m是注册handler和pattern的,hosts用于判断pattern是否包含了host的匹配。看看Handle()函数的定义会更清晰:

func (mux *ServeMux) Handle(pattern string, handler Handler) {mux.mu.Lock()defer mux.mu.Unlock()if pattern == "" {panic("http: invalid pattern")}if handler == nil {panic("http: nil handler")}if _, exist := mux.m[pattern]; exist {panic("http: multiple registrations for " + pattern)}if mux.m == nil {mux.m = make(map[string]muxEntry)}mux.m[pattern] = muxEntry{h: handler, pattern: pattern}if pattern[0] != '/' {mux.hosts = true}
}// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {mux.Handle(pattern, HandlerFunc(handler))
}

pattern为空或者handler为空时,都会panic。此外,想要定义重复的pattern,也会panic。如果pattern的第一个字符不是"/",则表示这个pattern是从主机名开始匹配的。

唯一需要注意的是,每个Handle()都会对ServeMux实例加上写锁。

以常用的DefaultServeMux为例,它是ServeMux的一个实例。当使用DefualtServeMux时,每调用一次Handle()或HandleFunc(),都意味着向这个DefaultServeMux的结构中的m字段添加pattern和对应的handler。由于加了写锁,如果使用多个goroutine同时启动多个web服务,在同一时刻将只能有一个goroutine启动的web服务能设置DefaultServeMux。当然,一般情况下不会使用goroutine的方式同时启动多个web服务。

第三方ServeMux

自带的默认的DefaultServeMux其实功能限制很大。比如请求的URL路径为"/images/123.png",想要匹配这个确实容易,但是想要取出其中的"123.png"字符串,DefaultServeMux就没法实现。

有一个非常强大的Gorilla工具包(www.gorillatoolkit.org),它有好几个功能,其中一个功能是提供multiplexer。

Go Web:自带的ServeMux multiplexer相关推荐

  1. Python+selenium 自动化高级应用篇:借助pyautogui实现web前端带轨迹拖拽功能,解决ActionChains拖拽失效问题

    有一些 web 前端的交互,必须有鼠标轨迹才能成功的实现拖拽功能. 而 selenium 自带的 ActionChains 方法,是一瞬间从 A 点到 B 点的. 解决思路: 利用元素返回的相对浏览器 ...

  2. eclipse发布web不带项目名的url

    默认发布后访问地址是: http://localhost:8080/huanle/ 要达到的效果是: http://localhost:8080/ 不带项目名的url的好处是,不用再在每个地址前加&l ...

  3. go语言web开发入门之多路复用器(multiplexer)

    1.简介 在go语言web开发中,请求到达服务器时,多路复用器(multiplexer)会对请求进行检查,并将请求重定向到正确的处理器进行处理. 处理器在接收到多路复用器转发的请求之后,会从请求中取出 ...

  4. AXIS2客户端代码连接C#web service带ntlm认证

    搞了两天的AXIS2连接带ntlm认证的web service,要吐血了,百度一堆,不是故作神秘的讲一大堆,就是代码给一半,装吧.... 国人就是,知道的不愿意说,说也只说一半,不知道的又装知道,真是 ...

  5. [心静不下来系列]bugku web继续 (带了标题)

    [2,1]矛盾---------- is_numeric在php里面是 是数字的意思 这个啊,只要是不是纯数字也可以, 试了一下num=1*1  只要是一个字符串就行....不管是算式也好,一串什么其 ...

  6. 【WEB】带边框的网页页面实现

    前言 这是编程入学者尝试各种技术的备忘记录和自我激励,内容非常简单而单纯. 正文 成品 样式参考    http://tenhou.net/ 上边框 http://tenhou.net/img/f0t ...

  7. 下一代 Web 应用模型 —— Progressive Web App (PWA)

    今年 9 月份的时候,<程序员>杂志社就邀请我写一篇关于 PWA 的文章.后来花式拖稿,拖过了 10 月的 QCon,11 月的 GDG DevFest,终于在 12 月把这篇长文熬了出来 ...

  8. html颜色主题,16 种更好看的 WEB 默认标准色 colors.css

    16 种更好看的 WEB 默认标准色 colors.css Sponsor 网页安全色有216中,但支持颜色名称作为颜色值的只有16种,分别是aqua, black, blue, fuchsia, g ...

  9. 下一代 Web 应用模型 —— Progressive Web App

    今年 9 月份的时候,<程序员>杂志社就邀请我写一篇关于 PWA 的文章.后来花式拖稿,拖过了 10 月的 QCon,11 月的 GDG DevFest,终于在 12 月把这篇长文熬了出来 ...

最新文章

  1. 长庆石油学校计算机97,我在浙江大学学习计算机技术 ----我在长庆油田会战的12年(十一)...
  2. 12bit的图像如何向8bit转化_【福联影像】10bit显示器比8bit专业在哪?想告别色彩断层必须要了解...
  3. R语言入门第三集 实验二:基本数据处理
  4. 改变UITableView的headerView、footerView背景颜色
  5. android组件通讯 Intent- 系统标准的Activity Action应用
  6. php模拟请求get请求,php模拟get请求方法总结
  7. Java-数据类型拓展
  8. 魅族17 Pro通过3C认证:魅族史上最强快充
  9. Java 的 List 与 Scala 的 Seq 相互转换
  10. Nmap 源代码学习四 软件简单使用
  11. Struts与MVC分层理解
  12. spring,springmvc,mybatis整合ssm框架出现ORA-02289:序列不存在问题
  13. js php后端 安全,前端JS RSA加密,PHP后端解密实现密码安全传输
  14. 水晶报表图表出现红叉叉的解决方法
  15. 常用的特征选择算法介绍
  16. wps html嵌入ppt,wps文档怎么插入打开幻灯片 WPS文字添加ppt幻灯片教程
  17. 机器学习告诉你,新型冠状病毒接下来将如何变异?
  18. java单链表反转(头插法)详解
  19. jdk11安装及网盘下载地址
  20. Jenkins 部署项目出现 Failed to connect to repository : Command git ls-remote -h http://gitlab. 128

热门文章

  1. 读取文本文件的最后n行
  2. 视频教程-从零开始自然语言处理-NLP
  3. 匹配系统Java开发,基于RFID的机场行李快速匹配系统的设计(Java,MySQL)
  4. 计算机辅助设计关键技术的新进展,【精品】柔性制造技术.doc
  5. 11.16模拟赛总结
  6. 发动机曲轴加工工艺与专用机床夹具设计(论文+CAD图纸+工序卡+过程卡+开题报告+任务书+翻译……)
  7. 基于BSV的存储证明
  8. 读《史蒂夫•乔布斯传》(一)
  9. 悟透JavaScript[转]
  10. 采用FPGA实现音频模数转换器