Go web之旅(路由篇)

据说Go语言设计出来就是为了解决web软件的并发等诸多问题的,所以Go语言又被称为互联网中的c语言。一般的web应用采用的是"请求-响应"模式。在Go web中数据请求与数据返回相当于是基于"请求-响应"模式的web程序的输入输出。而其中数据在不同地方或者叫层次上有不同的表现形式,在客户端上数据一般采用字符串形式体现,而在后台数据一般体现为结构体或对象,这中间的转换需要相应的工具。 用servlet/jsp直接开发过Java web程序的同学应该知道,在整个架构中必不可少的元素有web容器,web.xml.web容器必不可少大家应该无异议,但web.xml为什么说也必不可少呢?在web程序中一般采用的MVC三层,当在V层(视图层)向服务器端发送请求时,程序会到web.xml进行URL mapping,寻找相应的处理请求程序进行业务逻辑处理。在Java web中我们耳熟能详的三大框架struts2,spring,hibernate都只不过在不同的层次对servlet进行扩展而已.都离不开URL mapping,其实在Go web也是有这部分的,只不过换了一个不同的名字而已,叫路由。 什么是路由呢?从百度百科中可以得到路由的说明:路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程。其实它的作用就是路径选择。在上次文章中说过,在servlet/jsp中是在web.xml里实现URLmapping的,而使用了struts时,就将实现URLmapping这部分工作放在了struts中的配置文件里。Go web中的路由就路由选择这一功能上其实和URLmapping(URL映射)是相同的,但接触过或熟悉Go web开发的人肯定知道,Go web中的路由是特别的灵活。许多Go web中间件和框架都是对Go web路由进行封装的,将路由匹配这一工作从main中剥离出去成为单独一层。有人肯定有疑惑,为何要如此大费周章呢?其实这样做一可以减轻main的压力,二是让路由选择变得更加通用性;三是路由选择这部分代码实现其实有很多重复工作,这样剥离出去可以减少代码的重复。中间件Negroni就是这样实现的。 上面讲了这么多,那在Go web中到底什么是路由,路由又是如何实现路由选择的呢?

在go语言的http package里定义了路由的结构和相应的路由的函数:

type ServeMux struct {//定义路由规则
mu    sync.RWMutex//锁机制,因为并发处理需要一个锁

m     map[string]muxEntry//路由,采用map结构

hosts bool // whether any patterns contain hostnames

}

type muxEntry struct {//路由

explicit bool   //是否精准匹配

h        Handler//路由匹配后,所选择的处理

pattern  string //匹配字符串



}

基于路由的函数:

//match根据传递的path进行路由匹配,返回对应的Handler

func (mux *ServeMux) match(path string) (h Handler, pattern string)

//根据给定request中是否连接网络这个状态进行判断并返回对应的路由

//若request的Method 等于"CONNECT"则调用handler(host, path string)函数进行路由匹配

func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)

//handler(host, path string) 函数调用match(path string)进行路由匹配并返回对应的路由

func (mux *ServeMux) handler(host, path string) (h Handler, pattern string)

//ServeHttp实现了Handler接口,故它实际上也是一个Handler,内部调用handler

func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request)

//注册handler

func (mux *ServeMux) Handle(pattern string, handler Handler)

//注册handler函数(它是直接使用func来注册的)

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))
复制代码

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2016-01-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏蓝天

Tcpdump 的用法

更新时间:2005-12-26 11:55 阅读提示:第一种是关于类型的关键字,主要包括host,net,port, 例如 host 210.27.48.2,指...

1144
来自专栏SDNLAB

ODL碳版本模块开发及流程梳理

文章主要基于ODL碳版本,进行简单插件的构建、安装、部署,以一个插件开发为例,介绍ODL新版本开发过程中的一些具体问题。 ? 一、碳版本简易开发流程 1.1 开...

5258
来自专栏专栏

跨环境测试框架介绍-pytest的高级用法

本文将介绍针对测试和生产等不同测试环境下,维护一套可读性,追溯性强的测试用例的工具-pytest。

4704
来自专栏行者悟空

Hadoop之RPC机制

1131
来自专栏Java架构师进阶

java多线程高级教程,这些你都懂了吗?

一、countdownLatch和cyclicbarrier(这两个做多线程控制很好用,工作中会经常用到)

1004
来自专栏osc同步分享

How Tomcat Works, A Guide to Developing Your Own Java Servlet Container

1.1 socket网络通信基础 客户端使用主机地址和端口实例化一个socket,此socket通过输出流将字符串等传向服务器主机。 服务器使用端口号实例化一个...

2906
来自专栏Golang语言社区

即时通讯软件可以用GO语言实现吗

四个方面特点: 1. 并发支持 对于及时通讯、网络编程等方面,并发支持一定是并不可少的。 goroutine,用户态"线程",大家所说的协程,支持并发操作。已经...

29910
来自专栏蓝天

HBase的FlushLargeStoresPolicy多例族支持

众所周知,HBase的一个例族flush时,会导致所有例族都跟着被flush。在HBase-0.94的官方说明(http://hbase.apache.or...

731
来自专栏cs

python多线程知识点

Thread是线程类,有两种使用方法,直接传入要运行的方法或从Thread继承并覆盖run(): 构造方法: Thread(group=None, targ...

1032
来自专栏java技术学习之道

常见的缓存穿透,缓存击穿,缓存雪崩解决方案分析

4603

扫码关注云+社区

领取腾讯云代金券