net/http标准库

net/http标准库通常包括两个部分,客户端和服务器,我们可以通过ListenAndServe创建一个简陋的服务器

package main

import (
"net/http"
) func main() {
http.ListenAndServe("", nil)
}

这会使用默认的80端口进行网络连接,并且使用默认的多路复用器DefaultServeMux,我们也可以通过Server结构进行更详细的配置

func main() {
server := http.Server {
Addr: "127.0.0.1:80",
Handler: nil,
}
server.ListenAndServe()
}

处理器和处理函数

处理器

前面的代码会返回404响应,因为我们还没有为请求编写相应的处理器。一个处理器就是一个拥有ServeHTTPf方法的接口

type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}

我们通过实现这个接口来编写处理器

type MyHandler struct{}

func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, world")
} func main() {
handler := MyHandler{}
server := http.Server {
Addr: "127.0.0.1:80",
Handler: &handler,
}
server.ListenAndServe()
}

我们可以设置多个处理器

type HelloHandler struct{}

func (hello *HelloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello!")
} type WorldHandler struct{} func (world *WorldHandler) ServeHTTP(w http.ResponseWriter, r *http.Reuest) {
fmt.Fprintf(w, "world!")
} func main() {
hello := HelloHandler{}
world := WorldHandler{} server := http.Server {
Addr: "127.0.0.1:80",
}
http.Handle("/hello", &hello)
http.Handle("/world", &world) server.ListenAndServe()
}

我们看一下Handle函数再源码中的定义

func Handle(pattern string, handler Handler) {
DefaultServeMux.Handle(pattern, handler)
}

实际上是在调用DefaultServeMux的某个方法,前面我们已经提到过了DefaultServeMux是个默认多路复用器,实际上它也是个Handler处理器,因为他是ServeMux结构的一个实例,而ServeMux也实现了Handler接口的ServeHTTP方法。这样就可以对不同的请求做出不同的响应。

处理器函数

处理器函数是与处理器拥有同样行为的函数,它们与ServeHTTP拥有同样的函数签名。

func hello (w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello!")
} func main() {
server := http.Server {
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/hello", hello) server.ListenAndServe()
}

HandleFunc是Go语言拥有的一种函数类型,它可以把一个带有正确签名的f转换为带有方法f的handler。

来看看HandleFunc的源码

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
} func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
if handler == nil {
panic("http: nil handler")
}
mux.Handle(pattern, HandlerFunc(handler))
}

Handle函数是不是似曾相识!

串联多个处理器和处理器函数

func hello(w *http.ResponseWriter, r *Request) {
fmt.Fprintf(w, "Hello!")
} func log(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Log!")
h(w, r)
}
} func main() {
server := http.Server {
Addr: "127.0.0.1:8080",
}
http.HandleFunc("/hello", log(hello))
server.ListenAndServe()
}

其中HandlerFunc是实现了Handler接口的函数类型,源码定义:

type HandlerFunc func(ResponseWriter, *Request)

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}

ServeMux

ServeMux是一个HTTP请求多路复用器,负责接收HTTP请求并根据请求中的URL将请求重定向到正确的处理器。ServeMux包含一个映射,这个映射会将URL映射至相应的处理器。值得一提的是,ServeMux无法使用变量实现URL模式匹配,因此必要时我们完全可以用其它自建的多路复用器来代替ServeMux,如HttpRouter等高效轻量的第三方复用器

Go Web编程 第三章--接收请求的更多相关文章

  1. Go Web编程 第四章--处理请求

    请求和响应 Request结构 URL字段 Header字段 Body字段 Form, PostForm, MultipartForm字段 在处理器函数中,我们可以通过Request获取各个字段的详细 ...

  2. [转]Windows Shell 编程 第三章 【转自:http://blog.csdn.net/wangqiulin123456/article/details/7987901】

    第三章 操作文件 我依然清楚地记得,Windows95 的贝塔版出现的情形,它在朋友之间和学院中传播,好酷,全新的文件管理器,一种全图标,全彩色可客户化的界面,以及活泼的动画标识使得在文件拷贝和删除方 ...

  3. 读高性能JavaScript编程 第三章

    第三章  DOM Scripting  最小化 DOM 访问,在 JavaScript 端做尽可能多的事情. 在反复访问的地方使用局部变量存放 DOM 引用. 小心地处理 HTML 集合,因为他们表现 ...

  4. Windows核心编程 第三章 内核对象

    第3章内核对象 在介绍Windows API的时候,首先要讲述内核对象以及它们的句柄.本章将要介绍一些比较抽象的概念,在此并不讨论某个特定内核对象的特性,相反只是介绍适用于所有内核对象的特性. 首先介 ...

  5. windows核心编程---第三章 内核对象及句柄本质

      本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一块内存 ...

  6. 【1】python核心编程 第三章

    1.继续( \ ) 有两种例外情况一个语句不使用反斜线也可以跨行.在使用闭合操作符时,单一语句可以跨多行,例如:在含有小括号.中括号.花括号时可以多行书写.另外就是三引号包括下的字符串也可以跨行书写 ...

  7. python核心编程-第三章-个人笔记

    1.语句和语法 (1)反斜杠"\"表示语句继续.python良好的编程习惯是一行最后不超过80个字符,一行字符过多时便须用到反斜杠换行继续该语句. PS:在使用小括号.中括号.大括 ...

  8. JavaWeb核心编程之(三.5)HTTP请求和接受表单数据

    HTTP简介WEB浏览器与WEB拂去其之间的一问一答的交互过程, 必须遵循一定的规则,这个规则就是HTTP协议HTTP是hypertext transfer protocol(超文本传输协议)的简写, ...

  9. WEB安全第三篇--控制请求的艺术:CSRF和SSRF

    零.前言 最近做专心web安全有一段时间了,但是目测后面的活会有些复杂,涉及到更多的中间件.底层安全.漏洞研究与安全建设等越来越复杂的东东,所以在这里想写一个系列关于web安全基础以及一些讨巧的pay ...

随机推荐

  1. Python——列表的操作

    列表的操作:详细+易出错假设有两个列表:    list1 = [1,2,3]    list2 = ['a','b','c']列表的操作: 1.list.append()    append只接受一 ...

  2. Linux 内核驱动--多点触摸接口【转】

    转自:http://blog.csdn.net/joard_yang/article/details/6225937 译自:linux-2.6.31.14/Documentation/input/mu ...

  3. aarch64_m3

    mrpt-stereo-camera-calibration-1.4.0-1.fc26.aarch64.rpm 2017-03-17 10:02 143K fedora Mirroring Proje ...

  4. 使用数据库管理工具打开MySql

    1.推荐使用软件:Navicat_Premium_11.0.10.exe.  下载地址:http://pan.baidu.com/s/1nu6mTF7 2.下载上面文件并安装. 3.打开Navicat ...

  5. 004_MAC实用的小工具

    一.XtraFinder(右键菜单扩展) http://www.xuebuyuan.com/173454.html http://www.mamicode.com/info-detail-111618 ...

  6. parseObject方法将json字符串转换成Map

    String nwVal=recordDO.getWorkOrderNwVal(); HashMap<String,WxhcWorkOrderDO> nwMap=JSON.parseObj ...

  7. 排序算法——Shell排序

    二.Shell排序 Shell排序也叫“缩减增量排序”(disminishing increment sort),基于插入排序进行. Shell建议的序列是一种常用但不理想的增量序列:1,...,N/ ...

  8. docker centos:latest 使用 sshd

    一.术语 1.容器 很多用户在接触Docker 之初都会认为容器就是一种轻量级的虚拟机,但实际上,容器和虚拟机有非常大的区别.从根本形态上来看,容器其实就是运行在操作系统上的一个进程,只不过加入了对资 ...

  9. 打造 Laravel 优美架构 谈可维护性与弹性设计

    转载:https://juejin.im/post/5be4475c518825170559c044

  10. Python_oldboy_自动化运维之路_函数,装饰器,模块,包(六)

    本节内容 上节内容回顾(函数) 装饰器 模块 包 1.上节内容回顾(函数) 函数 1.为什么要用函数? 使用函数之模块化程序设计,定义一个函数就相当于定义了一个工具,需要用的话直接拿过来调用.不使用模 ...