http.ServeMux多路复用器的设置
package mainimport ("fmt""net/http"
)func first(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-first")
}func second(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-second")
}func main() {server := http.Server{Addr: "localhost:8888",Handler: nil,}http.HandleFunc("/first", first)http.HandleFunc("/second", second)server.ListenAndServe()}
以上代码中的 Handler: nil, 和 http.HandleFunc(“/first”, first)、http.HandleFunc(“/second”, second)会不会冲突?
在代码中,Handler: nil 和 http.HandleFunc 并不会冲突,这是因为 http.HandleFunc 实际上是在设置全局的 ServeMux,而 http.Server 结构体中的 Handler 字段,如果没有设置(或者设置为 nil),则会默认使用这个全局的 ServeMux。
以下是详细解释:
1.全局 ServeMux:
http 包中有一个全局的 ServeMux 实例,名为 defaultServeMux。当使用 http.ListenAndServe 或者 http.Serve 函数时,如果没有提供特定的 Handler,就会使用这个全局的 ServeMux 来分发请求。
2.http.HandleFunc:
这个函数是 http.Handle 的一个便捷版本,它将传入的函数作为处理器与指定的路径关联起来。这些处理器会被添加到全局的 defaultServeMux 中。
3.Handler: nil:
在 http.Server 结构体中,Handler 字段用于指定一个自定义的 Handler 或 Handler 链。如果这个字段被设置为 nil,那么 http.Server 会回退到使用全局的 defaultServeMux。
在代码中,server 结构体的 Handler 字段被设置为 nil,这意味着服务器将使用全局defaultServeMux 来处理请求。而 http.HandleFunc 正是将处理器添加到这个全局 ServeMux 中,所以它们之间不会冲突。
当服务器接收到一个请求时,http.Server 会查找 defaultServeMux 中与请求路径匹配的处理器,并调用它来处理请求。因此,即使 Handler 字段被设置为 nil,服务器仍然能够正确地响应 /first 和 /second 路径的请求,因为这些路径已经被 http.HandleFunc 与相应的处理器关联起来了。
package mainimport ("fmt""net/http"
)func first(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-first")
}func second(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-second")
}type handle struct {
}func (h *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) {w.Write([]byte("同一处理"))
}func main() {h := handle{}server := http.Server{Addr: "localhost:8888",Handler: &h,}http.HandleFunc("/first", first)http.HandleFunc("/second", second)server.ListenAndServe()}
如果Handler: &h,,会不会和 http.HandleFunc(“/first”, first)、http.HandleFunc(“/second”, second)冲突?
在代码中,Handler: &h 和 http.HandleFunc 之间确实存在冲突。这是因为 http.Server 结构体的 Handler 字段和 http.HandleFunc 函数使用了不同的 ServeMux 实例。
-
Handler: &h: 当在 http.Server 结构体中设置 Handler 为 &h 时,实际上是在告诉服务器使用 &h 作为其顶级处理器。这意味着所有的请求都会首先经过 &h 的 ServeHTTP 方法。如果没有在 &h 的 ServeHTTP 方法中显式地将请求分发到其他路由,那么 http.HandleFunc 设置的路由将不会被调用。
-
http.HandleFunc: http.HandleFunc 函数将特定的 URL 路径与特定的处理器函数关联起来,并将这些路由添加到全局的 ServeMux(defaultServeMux) 中。这些路由只有在没有为 http.Server 设置自定义 Handler 时才会被使用。
在代码中,由于 Handler: &h 被设置为 http.Server 的处理器,全局的 ServeMux(即http.HandleFunc 添加的路由所在的 ServeMux) 将不会被使用。因此,任何发送到 /first 或 /second 的请求都会被 &h 的 ServeHTTP 方法处理,而不会调用 first 或 second 函数。
要解决这个问题,您需要确保 http.Server 使用全局的 ServeMux 作为其处理器,或者在 &h 的 ServeHTTP 方法中显式地将请求分发到其他路由。以下是使用全局 ServeMux 的示例:
package mainimport ("fmt""net/http"
)func first(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-first")
}func second(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-second")
}type handle struct {
}func (h *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) {// 这里可以添加逻辑来处理特定的路径,或者直接使用默认的ServeMuxhttp.DefaultServeMux.ServeHTTP(w, r)
}func main() {h := handle{}server := http.Server{Addr: "localhost:8888",Handler: &h, // 使用自定义ServeMux}http.HandleFunc("/first", first)http.HandleFunc("/second", second)server.ListenAndServe()
}
在这个修改后的代码中,handle 结构体的 ServeHTTP 方法调用 http.DefaultServeMux.ServeHTTP,这样所有的请求都会通过全局的 ServeMux 来处理,包括通过 http.HandleFunc 设置的路由。这样就不会与 http.HandleFunc 设置的路由冲突了。
http.DefaultServeMux.ServeHTTP(w, r)这行代码发挥什么作用?
http.DefaultServeMux.ServeHTTP(w, r) 这行代码的作用是将接收到的 HTTP 请求 r 以及用于响应的 http.ResponseWriter 对象 w 传递给默认的 ServeMux 实例进行处理。
在 Go 的 net/http 包中,http.DefaultServeMux 是一个全局的 ServeMux 实例,它负责根据请求的 URL 路径分发请求到注册的处理器(handler)。当你调用 http.HandleFunc 或 http.Handle 时,实际上是在向这个全局的 ServeMux 注册路由。
当你在自定义的 http.Handler(如你的 handle 结构体中调 http.DefaultServeMux.ServeHTTP(w, r),你实际上是在告诉 Go 的 HTTP 服务器使用全局的路由规则来处理请求。这意味着,即使你的服务器使用了自定义的 http.Handler,它仍然会遵循通过 http.HandleFunc 或 http.Handle 设置的路由规则。
这样做的好处是,你可以在自定义的 http.Handler 中添加一些通用的处理逻辑,比如日志记录、认证、请求预处理等,然后再将请求交给全局的 ServeMux 来根据具体的路由规则进行处理。这样既保持了自定义处理的灵活性,又能够利用全局 ServeMux 的路由功能。
简而言之,http.DefaultServeMux.ServeHTTP(w, r) 允许你的自定义 http.Handler 与全局的路由规则协同工作,确保所有的路由设置都能被正确地应用到传入的请求上。
如何在 &h 的 ServeHTTP 方法中显式地将请求分发到其他路由?
在 Go 中,如果你想在自定义的 ServeHTTP 方法中显式地将请求分发到其他路由,你需要在你的 ServeHTTP 方法中实现一个逻辑,该逻辑会检查请求的 URL 并决定使用哪个处理器(handler)。以下是如何实现这一点的步骤:
1.检查请求路径:在你的 ServeHTTP 方法中,首先检查请求的 URL 路径。
2.调用相应的处理器:根据路径匹配结果,调用相应的处理器函数或结构体的 ServeHTTP 方法。
3.使用全局 ServeMux:如果你不想完全重写路由逻辑,可以使用全局的 ServeMu(http.DefaultServeMux)来处理请求,这可以通过调http.DefaultServeMux.ServeHTTP(w, r) 实现。
以下是一个示例代码,展示了如何在自定义 ServeHTTP 方法中显式分发请求:
package mainimport ("fmt""net/http"
)// 定义两个处理器函数
func first(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-first")
}func second(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-second")
}// 自定义ServeMux结构体
type handle struct{}// 实现ServeHTTP方法
func (h *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) {// 检查请求路径并分发请求if r.URL.Path == "/first" {first(w, r)} else if r.URL.Path == "/second" {second(w, r)} else {// 如果没有匹配的路径,使用默认的ServeMux处理http.DefaultServeMux.ServeHTTP(w, r)}
}func main() {h := handle{}server := http.Server{Addr: "localhost:8888",Handler: &h,}server.ListenAndServe()
}
在这个例子中,我们创建了一个自定义的 handle 结构体,并实现了 ServeHTTP 方法。在这个方法中,我们检查了请求的 URL 路径,并根据路径调用了相应的处理器函数。如果请求的路径不匹配任何已知路由,我们使用 http.DefaultServeMux.ServeHTTP(w, r) 将请求分发给全局的 ServeMux 处理,这样就能处理通过 http.HandleFunc 注册的路由。这种方法允许你在自定义的 ServeHTTP 方法中显式地控制请求的分发逻辑。
相关文章:
http.ServeMux多路复用器的设置
package mainimport ("fmt""net/http" )func first(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-first") }func second(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "多函数-second") }func ma…...

优化器与优化方法:在现代科学与工程中的应用
目录 编辑 优化器:机器学习中的参数调整 1. 梯度下降系列 2. 动量法(Momentum) 3. Adagrad 4. RMSprop 5. Adam 优化方法:寻找系统最优解 线性规划 非线性规划 凸优化 非凸优化 结论 在当今的科学和工程领域&#…...

笔记本外接显示屏没声音
1、笔记本正常有声音,但是外接显示屏后没有声音了怎么回事呢?原来外接显示屏后笔记本的声音输出会自动选择显示屏的音频输出,但是显示屏可能没有声音输出所以导致笔记本没有声音。 2、解决办法:打开笔记本设置,选择声…...
vue框架
Vue.js是一种用于构建用户界面的JavaScript框架。它是一个轻量级框架,被设计为逐渐采用的渐进式框架,可以与现有项目集成,也可以作为一个完整的单页应用程序框架使用。 Vue.js具有以下特点: 简单易学:Vue.js的API简单…...

Vue指令(一)--v-html、v-show、v-if、v-else、v-else-if、v-on、v-bind、v-for、v-model
目录 (一)初识指令和内容渲染指令v-html 1.v-html 案例: 官网的API文档 (二)条件渲染指令v-show和v-if 1. v-show 2. v-if (三)条件渲染指令v-else和v-else-if 案例 (四…...

ElK 8 收集 MySQL 慢查询日志并通过 ElastAlert2 告警至飞书
文章目录 1. 说明2. 启个 mysql3. 设置慢查询4. filebeat 设置5. 触发慢查询6. MySQL 告警至飞书 1. 说明 elk 版本:8.15.0 2. 启个 mysql docker-compose.yml 中 mysql: mysql:# restart: alwaysimage: mysql:8.0.27# ports:# - "3306:3306&q…...

QT通过在线安装器安装【详细】
在线安装器地址: 官方在线安装器:Index of /official_releases/online_installers (qt.io) 通过命令行启动安装页面 直接双击qt安装程序,在线安装会非常慢,甚至安装失败,所以通过命令行页面启动安装页面。点击wind…...

34.1 uber开源的m3db简介
本节重点介绍 : m3db自己的定位m3db自己的架构m3db自己的组件 两句话简介 M3最初是在优步开发的,目的是提供对优步业务运营,微服务和基础架构的可视性由于M3具有轻松进行水平扩展的能力,因此它为所有监视用例提供了一个集中式存储解决方案…...

MATLAB 最小二乘点云拟合球 (89)
MATLAB 最小二乘点云拟合球 (89) 一、算法介绍二、算法实现1.代码2.结果这是缘,亦是最美的相见 一、算法介绍 球面拟合算法是一种通过数学方法将一组三维点(通常在三维空间中分布)拟合到一个理想的球形表面上。这个过程通常涉及使用最小二乘法来最小化实际数据点与拟合的…...

【Altium Designer 】AD如何使用嘉立创元器件的3D封装
1.下载3D封装 以STM32F407VGT6为例,进入嘉立创商城网站,找到需要的元器件封装 复制编号,打开嘉立创EDA,编译器选择专业版,新建工程,点击PCB1 复制编号在搜索框中,点击搜索,然后放置…...

G15沈海高速茶白高架自动化监测
1. 项目简介 G15 沈海高速公路北起辽宁省沈阳市苏家屯区金宝台枢纽,与沈阳市绕城高速公路(国家高速 G1501)相接,南至海南省海口市秀英区粤海枢纽,与海南地区环线高速公路(国家高速 G98)相交&am…...

网站从渗透到mssql提权全过程
2|0渗透全过程 1.信息收集-端口探测 1)Nmap端口探测:namp -sS -p 1-65535 172.16.12.103 可以看到端口开放情况 2.判断系统情况 根据端口情况初步判定为IISmssql.net系统,访问web站点URL应该为:http:172.16.12.103:27689 访问…...
Qt多线程与QTimer详解
引用 Qt多线程中使用QTimer(常见问题汇总) [多线程]多线程使用QTimer Qt::ConnectionType:Qt不同类型connect的详细区别说明与应用 Qt的4种多线程实现方式 一文搞定之Qt多线程(QThread、moveToThread) QTimer The QTimer class provides repe…...

基于stm23的智慧宿舍系统 (DAY10)_小程序
好久没记录开发进度了,今天小程序差不多开发完了,UI这块算是比较常见了,主要功能是能连接onenet查看设备上传的数据,同时也能对设备进行一些控制下面是几个主要的函数,功能比较简单 wx.request({url: ${apiBaseUrl}/t…...

深入理解Spring事务
目录 什么是Spring事务为什么需要Spring事务Spring事务的实现 Spring事务的传播机制Spring事务的底层原理 EnableTransactionManagement --开启Spring管理事务Import(TransactionManagementConfigurationSelector.class) --提供两个beanAutoProxyRegistrar --启用AOP的功能&am…...

Ubuntu22.04深度学习环境安装【Anaconda+Pycharm】
anaconda可以提供多个独立的虚拟环境,方便我们学习深度学习(比如复现论文); Pycharm编辑器可以高效的编写python代码,也是一个很不错的工具。 下面就记录下Ubuntu22.04的安装流程: 1.Anaconda安装 下载Ana…...

五、docker的网络模式
五、docker的网络模式 5.1 Docker的四种网络模式 当你安装docker时,它会自动创建三个网络,可使用如下命令查看: [rootlocalhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 7390284b02d6 bridge bridge lo…...

使用el-row和el-col混合table设计栅格化,实现表头自适应宽度,表格高度占位
演示效果: 如上图,由于地址信息很长,需要占多个格子,所以需要错开,若想实现这种混合效果,可以这样搭建: 页面效果: 代码分析: 上面使用el-row和el-col搭建表单显示 第一排三个8,第二排8和16 下面混合table实现,并使用border来自适应宽度…...

【服务器监控】grafana+Prometheus+node exporter详细部署文档
我们在进行测试时,不可能一直手动看着服务器的性能消耗,这时候就需要有个工具替我们监控服务器的性能消耗。这里记录下grafanaPrometheusnodeExporter的组合用于监控服务器。 简单介绍: grafana:看板工具,所有采集的…...

JavaScript中todolist操作--待办事项的添加 删除 完成功能
效果图 在文本框中输入内容点击添加按钮会在下面生成 添加功能 html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&qu…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...