15分钟学 Go 第 41 天:中间件的使用
第41天:中间件的使用
目标:学习如何在Go语言的Web服务中使用中间件
中间件(Middleware)是Web开发中的一种常见设计模式,通常用于处理请求和响应过程中的一些共通功能。比如:日志记录、认证授权、请求处理、响应修改等。在Go语言的Web开发中,中间件是通过装饰器模式实现的,可以帮助我们在请求处理流程中插入额外的操作。
本节内容将带领你详细学习Go语言中如何使用中间件,尤其是在Web服务中。我们会通过以下几个方面来阐述这一主题:
- 中间件的定义和用途
- Go语言中间件的实现
- Go标准库
net/http
中的中间件实现 - 基于
gorilla/mux
的中间件实现 - 常见中间件案例:日志记录、身份验证、跨域处理
- 中间件执行流程图
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大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!
相关文章:
15分钟学 Go 第 41 天:中间件的使用
第41天:中间件的使用 目标:学习如何在Go语言的Web服务中使用中间件 中间件(Middleware)是Web开发中的一种常见设计模式,通常用于处理请求和响应过程中的一些共通功能。比如:日志记录、认证授权、请求处理…...
《Python 与 SQLite:强大的数据库组合》
《Python 与 SQLite:强大的数据库组合》 一、Python 与 SQLite 的结合二、安装与连接(一)安装 SQLite 模块(二)连接到数据库 三、数据库操作(一)创建表格(二)插入数据&am…...
Golang | Leetcode Golang题解之第552题学生出勤记录II
题目: 题解: const mod int 1e9 7type matrix [6][6]intfunc (a matrix) mul(b matrix) matrix {c : matrix{}for i, row : range a {for j : range b[0] {for k, v : range row {c[i][j] (c[i][j] v*b[k][j]) % mod}}}return c }func (a matrix) p…...
Vue3 常用代码指南手抄,超详细 cheatsheet
一、Vue3 基础 1.1 创建 Vue3 项目 使用 Vite 创建 npm create vitelatest my-vue-app -- --template vue cd my-vue-app npm install npm run dev使用 Vue CLI 创建 npm install -g vue/cli vue create my-vue-app1.2 项目结构 my-vue-app ├── node_modules ├── pu…...
结构体是否包含特定类型的成员变量
结构体是否包含特定类型的成员变量 在C中,可以使用模板元编程和类型特性(type traits)来判断一个结构体是否包含特定类型的成员变量。这通常通过std::is_member_object_pointer类型特性来实现,它可以用来检查给定的成员指针是否指…...
堆排序与链式二叉树:数据结构与排序算法的双重探索
大家好,我是小卡皮巴拉 文章目录 目录 引言 一.堆排序 1.1 版本一 核心概念 堆排序过程 1.2 版本二 堆排序函数 HeapSort 向下调整算法 AdjustDown 向上调整算法 AdjustUp 二.链式二叉树 2.1 前中后序遍历 链式二叉树的结构 创建链式二叉树 前序遍历…...
用 Python 从零开始创建神经网络(四):激活函数(Activation Functions)
激活函数(Activation Functions) 引言1. 激活函数的种类a. 阶跃激活功能b. 线性激活函数c. Sigmoid激活函数d. ReLU 激活函数e. more 2. 为什么使用激活函数3. 隐藏层的线性激活4. 一对神经元的 ReLU 激活5. 在隐蔽层中激活 ReLU6. ReLU 激活函数代码7. …...
使用 Flask 和 ONLYOFFICE 实现文档在线编辑功能
提示:CSDN 博主测评ONLYOFFICE 文章目录 引言技术栈环境准备安装 ONLYOFFICE 文档服务器获取 API 密钥安装 Flask 和 Requests 创建 Flask 应用项目结构编写 app.py创建模板 templates/index.html 运行应用功能详解文档上传生成编辑器 URL显示编辑器回调处理 安全性…...
【C++】【算法基础】序列编辑距离
编辑距离 题目 给定 n n n个长度不超过 10 10 10 的字符串以及 m m m 次询问,每次询问给出一个字符串和一个操作次数上限。 对于每次询问,请你求出给定的 n n n个字符串中有多少个字符串可以在上限操作次数内经过操作变成询问给出的字符串。 每个…...
【Android】轮播图——Banner
引言 Banner轮播图是一种在网页和移动应用界面设计中常见的元素,主要用于在一个固定的区域内自动或手动切换一系列图片,以展示不同的内容或信息。这个控件在软件当中经常看到,商品促销、热门歌单、头像新闻等等。它不同于ViewPgaer在于无需手…...
学SQL,要安装什么软件?
先上结论,推荐MySQLDbeaver的组合。 学SQL需要安装软件吗? 记得几年前我学习SQL的时候,以为像Java、Python一样需要安装SQL软件包,后来知道并没有所谓SQL软件,因为SQL是一种查询语言,它用来对数据库进行操…...
webstorm 设置总结
编辑器-》文件类型-》忽略的文件和文件夹-》加上node_modules 修改WebStorm 内存有两种方式。 1. 点击菜单中的Help -> change memory settings 弹出设置内存窗口,修改最大内存大小。然后点击Save and Restart 即可。 2. 点击菜单中的Help -> Edit Custom V…...
基于Spring Boot的养老保险管理系统的设计与实现,LW+源码+讲解
摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统养老保险管理系统信息管理难度大,容错率低&a…...
Java | Leetcode Java题解之第541题反转字符串II
题目: 题解: class Solution {public String reverseStr(String s, int k) {int n s.length();char[] arr s.toCharArray();for (int i 0; i < n; i 2 * k) {reverse(arr, i, Math.min(i k, n) - 1);}return new String(arr);}public void reve…...
sql分区
将学员表student按所在城市使用PARTITION BY LIST 1、创建分区表。 CREATE TABLE public.student( sno numeric(4,0), sname character varying(20 char),gender character varying(2 char), phone numeric(11,0), …...
[OpenGL]使用OpenGL实现硬阴影效果
一、简介 本文介绍了如何使用OpenGL实现硬阴影效果,并在最后给出了全部的代码。本文基于[OpenGL]渲染Shadow Map,实现硬阴影的流程如下: 首先,以光源为视角,渲染场景的深度图,将light space中的深度图存储…...
嵌入式采集网关(golang版本)
为了一次编写到处运行,使用纯GO编写,排除CGO,解决在嵌入式中交叉编译难问题 硬件设备:移远EC200A-CN LTE Cat 4 无线通信模块,搭载openwrt操作系统,90M内存...
ctfshow(328)--XSS漏洞--存储型XSS
Web328 简单阅读一下页面。 是一个登录系统,存在一个用户管理数据库。 那么我们注册一个账号,在账号或者密码中植入HTML恶意代码,当管理员访问用户管理数据库页面时,就会触发我们的恶意代码。 思路 我们向数据库中写入盗取管理员…...
【C#】Thread.CurrentThread的用法
Thread.CurrentThread 是 System.Threading.Thread 类的一个静态属性,它返回当前正在执行的线程对象。通过 Thread.CurrentThread,可以访问和修改当前线程的各种属性和方法。 下面是一些常见的用法和示例: 1. 获取当前线程的信息 使用 Thr…...
简单分享一下淘宝商品数据自动化抓取的技术实现与挑战
在电子商务领域,数据是驱动决策的关键。淘宝作为国内最大的电商平台之一,其商品数据对电商从业者来说具有极高的价值。然而,从淘宝平台自动化抓取商品数据并非易事,涉及多重技术和法律挑战。本文将从技术层面分析实现淘宝商品数据…...
Netty篇(入门编程)
目录 一、Hello World 1. 目标 2. 服务器端 3. 客户端 4. 流程梳理 💡 提示 5. 运行结果截图 二、Netty执行流程 1. 流程分析 2. 代码案例 2.1. 引入依赖 2.2. 服务端 服务端 服务端处理器 2.3. 客户端 客户端 客户端处理器 2.4. 代码截图 一、Hel…...
【渗透测试】payload记录
Java开发使用char[]代替String保存敏感数据 Java Jvm会提供内存转储功能,当Java程序dump后,会生成堆内存的快照,保存在.hprof后缀的文件中,进而导致敏感信息的泄露。char[]可以在存储敏感数据后手动清零,String对象会…...
2024自动驾驶线控底盘行业研究报告
自动驾驶线控底盘是实现自动驾驶的关键技术之一,它通过电子信号来控制车辆的行驶,包括转向、制动、驱动、换挡和悬架等系统。线控底盘技术的发展对于自动驾驶汽车的实现至关重要,因为它提供了快速响应和精确控制的能力,这是自动驾驶系统所必需的。 线控底盘由五大系统组成…...
css3D变换用法
文章目录 CSS3D变换详解及代码案例一、CSS3D变换的基本概念二、3D变换的开启与景深设置三、代码案例 CSS3D变换详解及代码案例 CSS3D变换是CSS3中引入的一种强大功能,它允许开发者在网页上创建三维空间中的动画和交互效果。通过CSS3D变换,你可以实现元素…...
Rust:启动与关闭线程
在 Rust 编程中,启动和关闭线程是并发编程的重要部分。Rust 提供了强大的线程支持,允许你轻松地创建和管理线程。下面将详细解释如何在 Rust 中启动和关闭线程。 启动线程 在 Rust 中,你可以使用标准库中的 std::thread 模块来创建和启动新…...
Ubuntu 的 ROS 2 操作系统安装与测试
引言 机器人操作系统(ROS, Robot Operating System)是一种广泛应用于机器人开发的开源框架,提供了丰富的库和工具,支持开发者快速构建、控制机器人并实现智能功能。 当前,ROS 2 的最新长期支持版本为 Humble Hawksbil…...
在双显示器环境中利用Sunshine与Moonlight实现游戏串流的同时与电脑其他任务互不干扰
我和老婆经常会同时需要操作家里的电脑,在周末老婆有时要用电脑加班上网办公,而我想在难得的周末好好地Game一下(在客厅用电视机或者平板串流),但是电脑只有一个,以往我一直都是把电脑让给老婆,…...
ElasticSearch备考 -- Cross cluster replication(CCR)
一、题目 操作在cluster1(local)中操作索引task,复制到cluster2(remote)中 二、思考 CCR 我们可以对标MySQL 理解为为主从,后者备份。主节点负责写入数据,从/备节点负责同步时主节点的数据。 …...
windows C#-异常处理
C# 程序员使用 try 块来对可能受异常影响的代码进行分区。 关联的 catch 块用于处理生成的任何异常。 finally 块包含无论 try 块中是否引发异常都会运行的代码,如发布 try 块中分配的资源。 try 块需要一个或多个关联的 catch 块或一个 finally 块,或两…...
边缘计算在智能制造中的应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 边缘计算在智能制造中的应用 边缘计算在智能制造中的应用 边缘计算在智能制造中的应用 引言 边缘计算概述 定义与原理 发展历程 …...
wordpress中文tag/seo外包杭州
一、引子顾名思义,进程即正在执行的一个过程。进程是对正在运行程序的一个抽象。进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一。操作系统的其他所有内容都是围绕进程的概念展开的。所…...
做网站的资料/青岛网站建设运营推广
目录 文章目录目录概述准备测试文件方法实例演练方法1: 通过重定向到null来清空文件内容方法2: 使用冒号":" 或 "true"命令重定向来清空文件方法3: 使用"echo -n "命令清空文件内容方法4: 使用truncate命令来清空文件内容方法5: 使用cat命令和/d…...
广州做网站哪家公司好/键词优化排名
B树 B树,也叫B-树,就是B-Tree(BalanceTree),是一种多路搜索树,它在文件系统中很有用,它不是二叉树,而是m(m>3)叉树,具有以下特征: 树中每个节点至多有m个结…...
自己做网站推广/官网制作公司
在本文中,我们将通过HLS自己动手实现一个AXI DMA,仿照的是官方AXI DMA IP核的直接模式,即给定发送起始地址和发送长度,以及接收起始地址和接收长度,就能进行一次DMA传输。 HLS设计 代码如下 dma.cpp #include"…...
三峡旅游景点网页制作素材/网站优化资源
linux的text模式下,想知道系统下安装了哪些软件包,以及软件包安装在哪个目录下,可以用以下命令,当然,可能还不止,我所知道的目前就是下面的这些。如果你还有新的,可以留言告诉我。1. which命令查…...
网站备案 费用/百度浏览器手机版
Visual Studio Code是Microsoft开发的一款开源免费的现代化轻量级代码编辑器,它体积小、启动快、系统内存占用率低非常适合搭建IDE。VSCode不仅支持几乎所有主流的开发语言的语法高亮、智能代码补全、自定义热键、括号匹配、代码片段、代码对比 Diff、GIT 等特性&am…...