Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Golang 语言怎么使用 net/http 标准库开发 http 应用?

Golang 语言怎么使用 net/http 标准库开发 http 应用?

作者头像
frank.
发布于 2021-06-22 09:23:33
发布于 2021-06-22 09:23:33
1.2K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,我是 frank。 欢迎大家点击上方蓝色文字「Golang 语言开发栈」关注公众号。 设为星标,第一时间接收推送文章。 文末扫码,一起学 Golang 语言。

01

介绍

在 Golang 语言中,可以使用 net/http 实现 http server,可以通过调用 ListenAndServe 函数,传入给定参数,地址和处理器 (handler)。处理器参数为 nil 时,默认使用 DefaultServeMux

也可以使用 net/http 标准库实现 http client。可以通过调用 GetHeadPost,和 PostForm 函数发送 http(或 https) 请求。需要注意的是,客户端完成请求后,必须关闭响应主体。

02

Server

使用 net/http 标准库实现 http server,通常有两种方式,分别是使用处理器和使用处理器函数。

处理器 Handler

其中,处理器方式包含单个处理器和多个处理器。

单个处理器,示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main () {
 hello := Hello{name: "frank"}
 httpServer := http.Server{Addr: ":8080", Handler: &hello}
 httpServer.ListenAndServe()
}

type Hello struct {
 name string
}

func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello " + h.name)
}

阅读上面这段代码,我们发现定义一个结构体类型的变量,通过实现 ServeHTTP(ResponseWriter, *Request) 方法,创建 Handler,并将其赋值给 http.Server 的 Handler 字段。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

阅读源码,可以发现 Handler 是包含一个 ServeHTTP(ResponseWriter, *Request) 方法的接口。

使用单个处理器的方式,方便传参,但是,不可以匹配多个路由,所以如果需要匹配多个路由,我们可以使用多个处理器的方式。

多个处理器,示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main () {
 httpServer := http.Server{
  Addr:              ":8080",
 }
 http.Handle("/hello", Hello{})
 http.Handle("/world", World{})
 httpServer.ListenAndServe()
}
type Hello struct {}
type World struct {}
func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello")
}
func (w1 World) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "world")
}

阅读上面这段代码,可以发现,我们创建了多个处理器,然后调用 http.Handle 函数,将处理器注册到 DefaultServeMux,多路复用器将路由请求转发给该路由的 ServerHTTP 方法处理。

使用多个处理器的方式,可以一个处理器匹配一个路由,通过创建多个处理器,可以匹配多个路由。

处理器函数

处理器方式,一个路由对应一个处理器(handler),当我们有多个路由时,需要创建多个处理器,使用上有些繁琐。因此,net/http 标准库提供了一个函数 HandleFunc,它可以将传参的路由和 handler func 注册到 DefaultServeMux

handler func 也实现了 Handler 结构体的 ServeHTTP(ResponseWriter, *Request) 方法。

处理器函数(handler func),示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main () {
 http.HandleFunc("/hello", hello)
 http.HandleFunc("/world", world)
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  log.Fatal(err)
 }
}
func hello(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello")
}
func world(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "world")
}

阅读上面这段代码,我们发现使用处理器函数的方式,相比使用处理器的方式,代码量减少了。但是,传参就变得不优雅了,我们在使用时可以根据场景择优选择。

聪明的读者朋友们可能发现,以上示例中使用的是 DefaultServeMux,为什么没有使用函数 http.NewServeMux 创建一个新的多路复用器?

因为 net/http 标准库会默认创建 DefaultServeMux。函数 http.Handlehttp.HandleFunc 将处理器注册到 DefaultServeMux,在 ListenAndServe 未接收到 handler 参数时,默认使用 DefaultServeMux

源码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func NewServeMux() *ServeMux { return new(ServeMux) }

var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux

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

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
 DefaultServeMux.HandleFunc(pattern, handler)
}

我们也可以创建一个新的多路复用器,管理路由请求,包含处理器模式和处理器函数模式。

处理器模式,示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main () {
 serveMux := http.NewServeMux()
 hello := Hello{}
 serveMux.Handle("/hello", hello)
 http.ListenAndServe(":8080", serveMux)
}

type Hello struct {}

func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello")
}

阅读上面这段代码,使用创建的多路复用器,调用多路复用器的 Handle 方法注册处理器(Handler)。

处理器函数模式,示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main () {
 serveMux := http.NewServeMux()
 hello := http.HandlerFunc(Hello)
 serveMux.Handle("/hello", hello)
 http.ListenAndServe(":8080", serveMux)
}

func Hello (w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello")
}

阅读上面这段代码,使用函数 http.HandlerFunc 将传入函数类型的参数转义为 HandlerFunc。

03

Client

使用 net/http 标准库实现 http client。可以通过调用 GetHeadPost,和 PostForm 函数发送 http(或 https) 请求。需要注意的是,客户端完成请求后,必须关闭响应主体。

示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main () {
 http.HandleFunc("/client", client)
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  log.Fatal(err)
 }
}
func client(w http.ResponseWriter, r *http.Request) {
 resp, err := http.Get("http://127.0.0.1:8080/hello")
 if err != nil {
  log.Fatal(err)
 }
 data, err := io.ReadAll(resp.Body)
 if err != nil {
  log.Fatal(err)
 }
 defer resp.Body.Close()
 fmt.Fprintln(w, string(data))
}

04

Request Param

关于接收请求参数,http.Request 也提供了一些函数和方法,限于篇幅,本文仅提供一个示例,对此不准备过多介绍。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main () {
 http.HandleFunc("/param1", param1)
 http.HandleFunc("/param2", param2)
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  log.Fatal(err)
 }
}
func param1(w http.ResponseWriter, r *http.Request) {
 r.ParseForm()
 fmt.Fprintln(w, r.Form["user"][0])
}
func param2(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, r.FormValue("user"), r.FormValue("age"))
}

阅读上面这段代码,我们定义了两个接收请求参数的函数,分别通过 r.ParseFormr.FormValue 方法获取请求参数,其中 r.ParseFome 方法是将参数解析到 r.Form 中,r.FormValue 方法直接返回一个字符串类型的给定参数 key 的第一个值。关于更多使用方式,请阅读官方文档。

05

Response Result

关于响应结果,http.ResponseWriter 接口也提供了三个方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type ResponseWriter interface {
 Header() Header
 Write([]byte) (int, error)
 WriteHeader(statusCode int)
}

限于篇幅,在此也不做过多介绍,仅提供一个示例。关于更多使用方式,请阅读官方文档。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main () {
 http.HandleFunc("/json", jsonRes)
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  log.Fatal(err)
 }
}
func jsonRes(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")
 ageStr := r.FormValue("age")
 ageInt, err := strconv.Atoi(ageStr)
 if err != nil {
  log.Fatal(err)
 }
 age := uint8(ageInt)
 username := r.FormValue("user")
 jsonData, err := json.Marshal(struct {
  Username string
  Age uint8
 }{username, age})
 if err != nil {
  log.Fatal(err)
 }
 fmt.Fprintln(w, string(jsonData))
}

06

总结

本文我们主要介绍使用 net/http 标准库实现 http server 和 http client 的使用方式。并简单列举了请求参数和响应结果的使用示例。关于 Cookie 的操作,在之前的公众号文章中介绍过,本文也没有重复赘述。

重点需要掌握的是处理器和多路复用器,包括处理器和处理器函数,以及新建多路复用器和默认多路复用器。此外,net/http 标准库还有几个内置函数,可以作为处理器,比如函数 NotFoundHandlerRedirectHandler 等。

阅读完本文,读者朋友们应该已经了解 Golang 语言怎么使用 net/http 标准库开发 http 应用。

参考资料: https://golang.org/pkg/net/http/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Go语言开发栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Go语言的网络编程简介
本文通过 Go 语言写几个简单的通信示例,从 TCP 服务器过渡到 HTTP 开发,从而简单介绍 net 包的运用。 TCP 服务器 首先来看一个 TCP 服务器例子 package main import ( "fmt" "log" "net" ) func main() { // net 包提供方便的工具用于 network I/O 开发,包括TCP/IP, UDP 协议等。 // Listen 函数会监听来自 8080 端口的连接,返回一个 net.Li
李海彬
2018/03/19
1.2K0
Go语言的网络编程简介
GO-Web 服务器的创建
Go 提供了一系列用于创建 Web 服务器的标准库,而且通过 Go 创建一个服务器的步骤非常简单,只要通过 net/http 包调用ListenAndServe 函数并传入网络地址以及负责处理请求的处理器( handler )作为参数就可以了。如果网络地址参数为空字符串,那么服务器默认使用 80 端口进行网络连接;如果处理器参数为 nil,那么服务器将使用默认的多路复用器 DefaultServeMux,当然,我们也可以通过调用 NewServeMux 函数创建一个多路复用器。多路复用器接收到用户的请求之后根据请求的 URL 来判断使用哪个处理器来处理请求,找到后就会重定向到对应的处理器来处理请求,
cwl_java
2020/04/08
1.1K0
go进阶-GO创建web服务+websocket详解
go提供了一系列用于创建web服务器的标准,而非常简单。只需要调用net/http包中的ListenAndServe函数并传入网络地址和负责处理的处理器就ok了。net/http库实现了整套的http服务中的客户端、服务端接口,可以基于此轻松的发起HTTP请求或者对外提供HTTP服务。
黄规速
2024/05/24
2.5K0
go进阶-GO创建web服务+websocket详解
Go 语言 Web 编程系列(三)—— 基于官方标准库自定义路由处理器
我们在上篇教程介绍过这段代码的底层实现,这里 http.ListenAndServe 方法第二个参数传入的是 nil,表示底层会使用默认的 DefaultServeMux 实现将上述 HandleFunc 方法传入的处理函数转化为基于闭包方式定义的路由:
学院君
2019/12/20
9720
Go 语言 Web 编程系列(三)—— 基于官方标准库自定义路由处理器
Go 源码学习之--net/http
其实自己不是很会看源码,但是学习优秀的源码是提升自己代码能力的一种方式,也可以对自己以后写代码有一个很好的影响,所以决定在之后的时间内,要有一个很好的习惯,阅读优秀的源码。刚开始自己会觉得看源码很痛苦,这个和我自己的方法有关系,刚开始自己总是想要知道源码的每一步操作,以及每个部分都是做什么,导致看着看着就看不下去了,所以也是从这次整理开始,调整自己阅读源码的方式,先去源码框架的主要流程,细枝末节后面等对整体框架有个了解,并且很清晰了,再回头来细致看,所以阅读过程中如果有不理解的地方自己先进行跳过,先对主体的
coders
2018/03/30
1.8K0
Go 源码学习之--net/http
深入理解Go标准库-ServeMux的使用与模式匹配
‍‍根据 Golang 文档 中的介绍,ServeMux是一个 HTTP 请求多路复用器(HTTP Request multiplexer)。它按照一定规则匹配请求URL和已注册的模式,并执行其中最匹配的模式的Handler
KevinYan
2023/12/13
6370
深入理解Go标准库-ServeMux的使用与模式匹配
Go语言入门——实践篇(五)
所谓Web开发,也就是我们通常说的网站后端开发。与其他语言相比,Go的Web开发具有简单易学,并发效率高,原生标准库支持等特点。即使是Python Web开发,也没有Go的简单。
arcticfox
2019/09/09
7540
Go语言入门——实践篇(五)
图文吃透Golang net/http 标准库--服务端
今天分享下Go语言net/http标准库的实现逻辑,文章将从客户端(Client)--服务端(Server)两个方向作为切入点,进而一步步分析http标准库内部是如何运作的。
小许code
2024/01/29
6770
图文吃透Golang net/http 标准库--服务端
[Introduction]万字手撕Go http源码server.go
从路由注册到监听本地端口后请求路由的一系列动作的分析,基本上仅限于net/http server.go这个包文件的路由相关部分解读
Wzy_CC
2020/08/28
1.3K0
【Go Web 篇】Go 语言进行 Web 开发:构建高性能网络应用
随着互联网的快速发展,Web 开发已经成为了软件开发领域中不可或缺的一部分。随之而来的是对于更高性能、更高效的网络应用的需求。在这个领域,Go 语言因其并发性能、简洁的语法以及丰富的标准库而备受关注。本篇博客将深入探讨如何使用 Go 语言进行 Web 开发,构建出高性能的网络应用。
繁依Fanyi
2023/10/12
1.5K0
【Go Web 篇】Go 语言进行 Web 开发:构建高性能网络应用
Go 每日一库之 net/http(基础和中间件)
几乎所有的编程语言都以Hello World作为入门程序的示例,其中有一部分以编写一个 Web 服务器作为实战案例的开始。每种编程语言都有很多用于编写 Web 服务器的库,或以标准库,或通过第三方库的方式提供。Go 语言也不例外。本文及后续的文章就去探索 Go 语言中的各个Web 编程框架,它们的基本使用,阅读它们的源码,比较它们优缺点。让我们先从 Go 语言的标准库net/http开始。标准库net/http让编写 Web 服务器的工作变得非常简单。我们一起探索如何使用net/http库实现一些常见的功能或模块,了解这些对我们学习其他的库或框架将会很有帮助。
用户7731323
2021/07/23
1.3K0
Go语言restful
在目前所学内容中每个请求都需要绑定一个HandlerFunc,而在实际项目中会有很多URL,且可能出现满足特定规律的URL,例如: /sxt/it和/sxt/baizhan都是以/sxt/开头.且如果这两个URL里面代码也差不多时,写两个Func就属于代码冗余了.
IT工作者
2022/03/31
2890
Go之Http包的服务端介绍
对于go的net/http包,主要分为两个部分,一部分是针对客户端的,一部分是针对服务端的,本篇文章主要介绍服务端这部分内容。
灰子学技术
2021/05/06
5100
Golang构建HTTP服务(二)--- Handler,ServeMux与中间件
Golang标准库http包提供了基础的http服务,这个服务又基于Handler接口和ServeMux结构的做Mutilpexer。实际上,go的作者设计Handler这样的接口,不仅提供了默认的ServeMux对象,开发者也可以自定义ServeMux对象。 本质上ServeMux只是一个路由管理器,而它本身也实现了Handler接口的ServeHTTP方法。因此围绕Handler接口的方法ServeHTTP,可以轻松的写出go中的中间件。 在go的http路由原理讨论中,追本溯源还是讨论Handler接
李海彬
2018/03/19
1.7K0
Golang构建HTTP服务(二)--- Handler,ServeMux与中间件
深入学习用Go编写HTTP服务器
Go是一门通用的编程语言,想要学习 Go 语言的 Web 开发,就必须知道如何用 Go 启动一个 HTTP 服务器用于接收和响应来自客户端的 HTTP 请求。用 Go实现一个http server非常容易,Go 语言标准库net/http自带了一系列结构和方法来帮助开发者简化 HTTP 服务开发的相关流程。因此,我们不需要依赖任何第三方组件就能构建并启动一个高并发的 HTTP 服务器。这篇文章会学习如何用net/http自己编写实现一个HTTP Serverk并探究其实现原理,以此来学习了解网络编程的常见范式以及设计思路。
KevinYan
2020/02/17
2.5K0
深入学习用Go编写HTTP服务器
golang(GO语言)http详解简单基础
因为好像长时间的写PHP可能大家感觉烦躁了,所以写一点golang的东西大家可以拿去玩玩,golang在web开发中让你得心应手,其实也是很好的东西,只要你玩进去之后感觉好爽,感觉比PHP的好处就是没有那么多的“限制”,基础部分大家可以看下简单的我再前边更新了一点点后边会继续给大家补上的,以后就是PHP+golang也可能会写一些object-c的,废话不多说开始写了,所有的代码我放在BUYVM上搭建的GOweb 大家可以去http://www.lingphp.com:8080/demo/查看获取完整代码,
李海彬
2018/03/22
1.5K0
Go语言经典库使用分析(七)| 高性能可扩展 HTTP 路由 httprouter
Go语言(golang)的一个很大的优势,就是很容易的开发出网络后台服务,而且性能快,效率高。在开发后端HTTP网络应用服务的时候,我们需要处理很多HTTP的请求访问,比如常见的API服务,我们就要处理很多HTTP请求,然后把处理的信息返回给使用者。对于这类需求,Golang提供了内置的net/http包帮我们来处理这些HTTP请求,让我们可以比较方便的开发一个HTTP服务。
飞雪无情
2020/02/10
1.2K0
Golang构建HTTP服务(一)--- net/http库源码笔记
实现一个最简单HTTP server需要多少代码?只需要一行,Python2的python -m SimpleHTTPServer,ruby的ruby -run -e httpd . -p 8888。对于Golang,实现一个最简单的http server也用不着几行,却能带来更具杀伤力的性能。 一个Go最简单的http服务器: package main import ( "fmt" "net/http" ) func IndexHandler(w http.ResponseWriter
李海彬
2018/03/19
1.9K0
Golang构建HTTP服务(一)--- net/http库源码笔记
Go 使用标准库 net/http 包构建服务器
在 Go 语言中,使用标准库 net/http 可以很方便的构建服务器,只要调用 ListenAndServe 函数,并传入参数IP地址与端口组成的字符串和处理器(handler)即可。
frank.
2020/09/27
1.4K0
Golang深入浅出之-Go语言标准库net/http:构建Web服务器
Go语言以其简洁的语法和强大的并发模型,成为构建高性能Web服务器的优选语言之一。其标准库中的net/http包提供了构建HTTP服务器和客户端的所有必要工具。本文旨在深入浅出地讲解net/http包的使用,分析在构建Web服务器过程中常见的问题、易错点,并提出避免策略,辅以实用代码示例。
Jimaks
2024/04/28
1.7K0
相关推荐
Go语言的网络编程简介
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档