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…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
