浙江 外贸网站建设/百度推广登录首页网址
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…...

Windows中MySQL8.3.4 MSI版本——详细安装教程
一、下载MySQL安装文件。 下载地址:MySQL官网 进入后点击下面的MySQL社区版下载 点击MySQL Comunity Server。 我这里选择的是版本8.4.3LTS版本,在线对应的msi文件。 点击No thanks,直接下载。 二、安装MySQL 2.1、双击刚刚下载好的msi文件,…...

MySQL-DDL之数据库操作
文章目录 一. 创建数据库1. 直接创建数据库,如果存在则报错2. 如果数据库不存在则创建3. 创建数据库时设置字符集4. 栗子 二. 查看数据库1. 查看数据库 三. 删除数据库1. 删除数据库 四. 使用数据库1. 使用数据库2. 查看正在使用的数据库 数据定义语言:简…...

Python 笔记之进程通信
当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程 但是如果是上百个或者上千个目标,手动去创建进程的工作量很大,此时就可以利用到Multiprocessing模块提供的Pool方法 初始化pool时,可以指定…...

【Transformer序列预测】Pytorch中构建Transformer对序列进行预测源代码
Python,Pytorch中构建Transformer进行序列预测源程序。包含所有的源代码和数据,程序能够一键运行。此程序是完整的Transformer,即使用了Encoder、Decoder和Embedding所有模块。源程序是用jupyterLab所写,建议分块运行。也整理了.p…...

生产者-消费者模式:多线程并发协作的经典案例
生产者-消费者模式是多线程并发编程中一个非常经典的模式,它通过解耦生产者和消费者的关系,使得两者可以独立工作,从而提高系统的并发性和可扩展性。本文将详细介绍生产者-消费者模式的概念、实现方式以及应用场景。 1 生产者-消费者模式概述…...

数据库-mysql(基本语句)
演示工具:navicat 连接:mydb 一.操作数据库 1.创建数据库 ①create database 数据库名称 //普通创建 ②create database if not exists 数据库名称 //创建数据库,判断不存在,再创建: 使用指定数据库 use 数据库…...

android12L super.img 解压缩及其挂载到ubuntu18.04
本文介绍如何在Ubuntu18.04上解压缩高通平台Android12L的super.img,并将其挂载到系统中查看内容。 在源码的根目录下,执行如下命令: out/host/linux-x86/bin/simg2img out/target/product/msmnile_gvmq/super.img super.img_rawmkdir super…...

flask简易版的后端服务创建接口(python)
1.pip install安装Flask和CORS 2.创建http_server.py文件,内容如下 """ ============================ 简易版的后端服务 ============================ """ from flask import Flask, request, jsonify from flask_cors import CORS app = F…...

小程序入门学习(四)之全局配置
一、 全局配置文件及常用的配置项 小程序根目录下的 app.json 文件是小程序的全局配置文件。常用的配置项如下: pages:记录当前小程序所有页面的存放路径 window:全局设置小程序窗口的外观 tabBar:设置小程序底部的 tabBar 效…...

PHP使用RabbitMQ(正常连接与开启SSL验证后的连接)
代码中包含了PHP在一般情况下使用方法和RabbitMQ开启了SSL验证后的使用方法(我这边消费队列是使用接口请求的方式,每次只从中取出一条) 安装amqp扩展 PHP使用RabbitMQ前,需要安装amqp扩展,之前文章中介绍了Windows环…...