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))
复制代码
- Java基础-21(02)总结字符流,IO流编码问题,实用案例必做一遍
- DeDeCMS v5.7 密码修改漏洞分析
- Java基础-20(01)总结,递归,IO流
- 一个Oracle bug的手工修复(r6笔记第59天)
- 由drop datafile导致的oracle bug(r6笔记第56天)
- Java中static关键字的作用
- Java基础-20(02)总结,递归,IO流
- Hive四种数据导入方式
- 34c3 部分Web Writeup
- 原来Oracle也不喜欢“蜀黍"(r6笔记第54天)
- Java基础19(01)总结IO流,异常try…catch,throws,File类
- 使用shell生成orabbix自动化配置脚本(r6笔记第53天)
- 现在 tensorflow 和 mxnet 很火,是否还有必要学习 scikit-learn 等框架?
- 数据的标准化与中心化以及R语言中的scale详解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Angular里的消息(Message)显示
- Angular应用内路由(In App Route)的最佳实践
- Angular应用的路由指令RouterLink
- ctfhub-信息泄泄露_备份文件下载
- Angular In-memory Web API使用介绍
- 攻防世界-php_rce
- 无法添加某个relationship给SAP CRM Product category的一个可能原因
- 记一次DataGuard SWITCHOVER_STATUS 状态为RESOLVABLE GAP的处理
- ABAP数据库表的元数据
- ctfshow-萌新赛
- VC++ libcurl FTP上传客户端程序
- Oracle RAC变更实验之修改11gR2+公网IP地址(网段不变)
- C# 纯控制台创建一个全屏窗口
- MySQL MHA部署添加Linux/Unix基本信息至Django中
- 记一次innobackupex导致的从库无法同步的问题