15分钟学 Go 第 41 天:中间件的使用

第41天:中间件的使用

目标:学习如何在Go语言的Web服务中使用中间件

中间件(Middleware)是Web开发中的一种常见设计模式,通常用于处理请求和响应过程中的一些共通功能。比如:日志记录、认证授权、请求处理、响应修改等。在Go语言的Web开发中,中间件是通过装饰器模式实现的,可以帮助我们在请求处理流程中插入额外的操作。

本节内容将带领你详细学习Go语言中如何使用中间件,尤其是在Web服务中。我们会通过以下几个方面来阐述这一主题:

  1. 中间件的定义和用途
  2. Go语言中间件的实现
  3. Go标准库net/http中的中间件实现
  4. 基于gorilla/mux的中间件实现
  5. 常见中间件案例:日志记录、身份验证、跨域处理
  6. 中间件执行流程图

1. 中间件的定义和用途

在Web应用程序中,中间件通常是指位于客户端请求和服务器响应之间的一个或多个处理组件。这些组件可以:

  • 修改请求:比如添加请求头、解析请求体等。
  • 控制请求流:比如进行身份验证,检查用户是否有权限访问某些资源。
  • 记录日志:记录访问日志、错误日志等。
  • 修改响应:如修改返回的内容、设置响应头等。

中间件的特点是,它是独立的功能单元,能够插入到请求处理链的任意位置,并且每个中间件组件只负责某一特定功能。


2. Go语言中间件的实现

在Go语言中,中间件通常是一个函数,它接收一个http.Handler接口类型的参数,返回一个新的http.Handler,通常在返回的新http.Handler中会对请求或响应进行处理。

Go中间件的一般签名如下:

type Middleware func(http.Handler) http.Handler

其中,http.Handler是Go语言标准库中定义的接口类型,用于处理HTTP请求。中间件的作用是将请求传递到下一个处理器。

3. Go标准库net/http中的中间件实现

Go标准库中的net/http包是处理HTTP请求和响应的核心。我们可以通过定义一个函数来实现中间件。

下面是一个简单的示例,展示了如何在Go语言中使用中间件进行日志记录:

示例代码:简单的日志记录中间件
package mainimport ("fmt""log""net/http""time"
)// 定义中间件类型
type Middleware func(http.Handler) http.Handler// 日志记录中间件
func LoggingMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {start := time.Now()log.Printf("Started %s %s", r.Method, r.URL.Path)next.ServeHTTP(w, r)log.Printf("Completed in %v", time.Since(start))})
}// 处理请求的实际处理器
func HelloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "Hello, World!")
}func main() {// 创建一个路由器mux := http.NewServeMux()// 将处理器注册到路由器mux.HandleFunc("/", HelloHandler)// 包裹中间件handler := LoggingMiddleware(mux)// 启动HTTP服务器log.Fatal(http.ListenAndServe(":8080", handler))
}
代码解析
  • LoggingMiddleware是我们定义的日志中间件,它接收一个http.Handler,并返回一个新的http.Handler
  • HelloHandler是一个简单的请求处理函数,当访问根路径时返回“Hello, World!”。
  • LoggingMiddleware会在请求开始时记录请求的路径和方法,然后调用next.ServeHTTP(w, r)来将请求传递给下一个处理器,最后记录请求的处理时间。

运行该代码后,在终端你会看到类似以下的日志:

Started GET /
Completed in 500ns

4. 基于gorilla/mux的中间件实现

gorilla/mux是一个非常流行的Go语言路由器,它支持中间件的功能,能够让我们更方便地组织和使用中间件。

下面是一个使用gorilla/mux的中间件示例:

示例代码:基于gorilla/mux的中间件实现
package mainimport ("fmt""log""net/http""time""github.com/gorilla/mux"
)// 日志记录中间件
func LoggingMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {start := time.Now()log.Printf("Started %s %s", r.Method, r.URL.Path)next.ServeHTTP(w, r)log.Printf("Completed in %v", time.Since(start))})
}// 处理请求的实际处理器
func HelloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "Hello, Gorilla Mux!")
}func main() {// 创建一个mux路由r := mux.NewRouter()// 将处理器注册到路由器r.HandleFunc("/", HelloHandler).Methods("GET")// 包裹中间件r.Use(LoggingMiddleware)// 启动HTTP服务器log.Fatal(http.ListenAndServe(":8080", r))
}
代码解析
  • 我们通过mux.NewRouter()创建了一个新的路由器。
  • 使用r.Use(LoggingMiddleware)将日志记录中间件应用到整个路由器。
  • 在请求被处理前和处理后,都会通过LoggingMiddleware记录日志信息。

运行该代码,访问http://localhost:8080/,你会看到与上一个示例类似的日志输出。


5. 常见中间件案例

除了日志记录中间件,Web开发中还有一些其他常见的中间件,我们将在此列举并展示如何在Go中实现。

1. 认证和授权中间件

认证中间件用于验证用户是否已登录或是否拥有访问某些资源的权限。下面是一个简单的身份验证中间件:

func AuthMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {authHeader := r.Header.Get("Authorization")if authHeader == "" {http.Error(w, "Forbidden", http.StatusForbidden)return}// 假设我们只是简单地检查一个固定的tokenif authHeader != "Bearer secret-token" {http.Error(w, "Forbidden", http.StatusForbidden)return}next.ServeHTTP(w, r)})
}
2. 跨域资源共享(CORS)中间件

CORS中间件用于处理跨域请求,它通常会添加Access-Control-Allow-Origin等头信息,允许来自其他域的请求。

func CORSMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {w.Header().Set("Access-Control-Allow-Origin", "*")w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")w.Header().Set("Access-Control-Allow-Headers", "Content-Type")next.ServeHTTP(w, r)})
}
3. 请求限流中间件

请求限流中间件用于限制客户端的请求频率,防止服务器过载。可以根据具体需求实现如IP限流、用户限流等策略。


6. 中间件执行流程图

我们通过以下的流程图来帮助理解Go Web服务中中间件的执行顺序:

┌────────────────────────┐
│        请求到达         │
└────────────────────────┘│▼┌─────────────────────┐│  进入第一个中间件      │└─────────────────────┘│▼┌─────────────────────┐│  第一个中间件处理      │└─────────────────────┘│▼┌───────────────────┐│  进入第二个中间件    │└───────────────────┘│▼┌───────────────────┐│  第二个中间件处理    │└───────────────────┘│▼┌────────────────┐│  请求到达处理器  │└────────────────┘│▼┌────────────────┐│  返回响应       │└────────────────┘│▼┌───────────────────┐│  进入响应中间件     │└───────────────────┘│▼┌───────────────────┐│  响应中间件处理     │└───────────────────┘│▼┌────────────────┐│  响应发送给客户端 │└────────────────┘

总结

中间件是Go语言Web开发中非常重要的组成部分,能够帮助我们处理请求、响应,增加一些通用的功能。在本节中,我们深入探讨了Go语言如何实现中间件,涵盖了日志记录、中间件链、认证授权等实际应用。希望你能通过这些示例理解中间件的工作原理,并能够在自己的Web项目中灵活使用。


怎么样今天的内容还满意吗?再次感谢观众老爷的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/7529.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

提高交换网络可靠性之认识STP根桥与端口角色

转载请注明出处 该实验旨在学习如何选举根桥与识别端口角色。 1.三台交换机按要求连线,改名,分别为S1,S2,S3,以S1为例: 2.在S1上配置优先级为28672 同理,在交换机S2和S3上配置其优先级为32768&…

qt QTextDocument详解

1、概述 QTextDocument是Qt框架中用于处理文本文档的类,它提供了丰富的功能和接口,用于创建、编辑和格式化文本内容。该类能够保存格式化的文本,是结构化富文本文档的容器,支持样式文本和各种文档元素,如列表、表格、…

【UE5】在材质中实现球形法线技术,常用于改善植物等表面的渲染效果

在材质中实现球形法线,这种技术常用于植被渲染等场景。通过应用球形法线可以显著提升植物再低几何体情况下的光照效果。 三二一上截图! 当然也可以用于任何你希望模型圆润的地方,下图中做了一个Cube倒角

提高交换网络可靠性之链路聚合

转载请注明出处 该实验为链路聚合的配置实验。 1.改名,分别将交换机1和交换机2改名为S1,S2,然后查看S1,S2的STP信息。以交换机1为例👇。 2.交换机S1,S2上创建聚合端口,将端口加入聚合端口。以S…

ZISUOJ 2024算法基础公选课练习一(3)

前言、 接&#xff08;2&#xff09;后完成I-J两道题 一、题目总览 二、具体题目 2.1 问题 I: 帆帆的图&#xff1a; 思路&#xff1a; 考察拓扑排序和图论&#xff08;拓扑排序也是排序&#xff0c;<滑稽>&#xff09;&#xff0c;都是模板&#xff0c;我就直接拿去…

窨井监测遥测终端RTU IP68防水强信号穿透力

在窨井的潮湿 黑暗和腐蚀性环境中 常规物联网设备往往难以生存 如何突破层层环境挑战 轻松应对极端条件 确保信号 24h不掉线&#xff0c;不延迟 不仅是对技术的突破 更是对恶劣环境的征服 ↓↓↓ 坚守 ——严苛环境下的工业设备 计讯物联工业级设备&#xff0c;专为恶劣环境设计…

python opencv3

三、图像预处理2 1、图像滤波 为图像滤波通过滤波器得到另一个图像。也就是加深图像之间的间隙&#xff0c;增强视觉效果&#xff1b;也可以模糊化间隙&#xff0c;造成图像的噪点被抹平。 2、卷积核 在深度学习中&#xff0c;卷积核越大&#xff0c;看到的信息越多&#xff0…

Mac上的免费压缩软件-FastZip使用体验实测

FastZip是Mac上的一款免费的压缩软件&#xff0c;分享一下我在日常使用中的体验 压缩格式支持7Z、Zip&#xff0c;解压支持7Z、ZIP、RAR、TAR、GZIP、BZIP2、XZ、LZIP、ACE、ISO、CAB、PAX、JAR、AR、CPIO等所有常见格式的解压 体验使用下来能满足我所有的压缩与解压的需求&a…

网络自动化04:python实现ACL匹配信息(主机与主机信息)

目录 背景分析代码代码解读代码总体结构1. load_pattern_from_excel 函数2. match_and_append_pattern 函数3. main 函数总结 最终的效果&#xff1a; 今天不分享netmiko&#xff0c;今天分享一个用python提升工作效率的小案例&#xff1a;acl梳理时的信息匹配。 背景 最近同事…

Linux之sed命令详解

文章目录 &#x1f34a;自我介绍&#x1f34a;sed概述&#x1f34a;sed语法讲解格式&#xff1a;options 命令选项{commmand}[flags] &#x1f34a;场景训练 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff…

用ChatGPT完成高质量文献综述全过程实操指南,用高级学术版专业应用gpts轻松搞定

文献综述在学术研究中占据核心地位,不仅为研究提供坚实的理论基础,也是创新观点和理论框架构建的重要支柱。然而,撰写高质量的文献综述往往是一项复杂且繁重的工作,需要研究者对领域内的文献进行广泛筛选、分类、对比和整合。该过程不仅考验研究者的分析能力,还要求对文献…

Java题目笔记(十四)Date +综合练习

一、时间计算时间比较 import java.util.Date; import java.util.Random;public class Main {public static void main(String[] args) {//需求1Date d1new Date(0L); //从时间原点开始经过了0毫秒long timed1.getTime();timetime1000L*60*60*24*365; //一年的时间d1.setTime(…

【C++练习】计算应发利润总数

题目&#xff1a;计算应发利润总数 问题描述&#xff1a; 某公司根据销售额 x&#xff08;单位&#xff1a;元&#xff09;计算应发利润总数 y&#xff08;单位&#xff1a;元&#xff09;&#xff0c;具体计算规则如下&#xff1a; 如果销售额 x 小于等于 100,000 元&#…

Permissions 0755 for ‘/etc/ssh/ssh_host_rsa_key‘ are too open.问题解决

1、问题背景 代码上库公司git后,将项目上出的程序烧录到设备中,wifi能够正常链接&#xff0c;但是通过wifi链接 ssh登录设备失败。把调试串口引出,查看linux启动log,发现如下打印信息&#xff1a; WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 075…

企业网络架构基础

1.网络宇宙 似宇宙洪荒&#xff0c;浩瀚无边&#xff0c;深不可测&#xff1b;网络案例似璀璨群星&#xff0c;千变万化&#xff0c;闪耀环宇。学习网络技术似夜观星象&#xff0c;每有所得&#xff0c;便拍案惊奇&#xff0c;夜不能寐 2.企业网络 企业网络已经广泛应用在各行…

Vue 3 的 全局状态管理

1.思路梳理 工厂仓拣货信息&#xff1a;Factory Picking Info (FPI)工厂仓调度信息&#xff1a;Factory Scheduling Info (FSI)DC 收货信息&#xff1a;DC Receiving Info (DCRI)上架信息&#xff1a;Shelving Info (SI)盘点信息&#xff1a;Inventory Count Info (ICI)移位信…

基于Spring Boot的在线装修管理系统的设计与实现,LW+源码+讲解

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#…

神经网络基础--什么是正向传播??什么是方向传播??

前言 本专栏更新神经网络的一些基础知识&#xff1b;这个是本人初学神经网络做的笔记&#xff0c;仅仅堆正向传播、方向传播就行了了一个讲解&#xff0c;更加系统的讲解&#xff0c;本人后面会更新《李沐动手学习深度学习》&#xff0c;会更有详细讲解;案例代码基于pytorch&a…

移动电源充气泵SIC8833应用方案设计

电动充气泵方案基于简单原理&#xff0c;使用时能自动检测轮胎压力。当胎压低于预设值时&#xff0c;电机自动启动&#xff0c;将压缩气体经进气管泵入轮胎。一旦充气泵达到设定的胎压上限&#xff0c;电机将自动关闭。该方案由压力传感器、ADC芯片、主控芯片等核心组件构成。其…

IP Source Guard

一、什么是IP Source Guard IP Source Guard&#xff08;IPSG&#xff09;是一种基于 IP/MAC 的端口流量过滤技术&#xff0c;用于防止局域网内的 IP 地址欺骗攻击。 隔绝非法DHCP服务器&#xff1a;通过配置非信任端口&#xff0c;IPSG可以有效阻止非法DHCP服务器向网络中的…