当前位置: 首页 > news >正文

01 Go Web基础_20240728 课程笔记

概述

如果您没有Golang的基础,应该学习如下前置课程。
在这里插入图片描述

基础不好的同学每节课的代码最好配合视频进行阅读和学习,如果基础比较扎实,则阅读本教程巩固一下相关知识点即可,遇到不会的知识点再看视频。

视频课程

最近发现越来越多的公司在用Golang了,所以精心整理了一套视频教程给大家,这个是其中的第3部,后续还会有很多。

视频已经录制完成,完整目录截图如下:
在这里插入图片描述

课程目录

  • 01 第一个Web程序.mp4
  • 02 默认的多路复用器.mp4
  • 03 自定义多路复用器.mp4
  • 04 配置读写超时时间.mp4
  • 05 httprouter库的介绍和安装.mp4
  • 06 httprouter的第一个使用案例.mp4
  • 07 使用httprouter提取路径参数.mp4
  • 08 复现浏览器跨域的问题.mp4
  • 09 使用httprouter分发二级域名.mp4
  • 10 使用httprouter挂载静态文件目录.mp4
  • 11 使用httprouter进行全局异常捕获.mp4
  • 12 将httprouter的代码下载到本地.mp4
  • 13 使用本地化的httprouter.mp4
  • 14 给本地化的httprouter打标签.mp4
  • 15 使用指定标签的本地化httprouter.mp4
  • 16 带参数的自定义处理器.mp4
  • 17 获取请求信息.mp4

每节课的代码

01 第一个Web程序.mp4

package mainimport ("fmt""net/http"
)func hello(w http.ResponseWriter, req *http.Request) {fmt.Fprintf(w, "hello world!")
}func main() {server := &http.Server{Addr: "0.0.0.0:8888",}http.HandleFunc("/", hello)server.ListenAndServe()
}

02 默认的多路复用器.mp4

package mainimport ("fmt""net/http"
)// 定义多个处理器
type handle1 struct{}
type handle2 struct{}func (h *handle1) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "handle1")
}
func (h *handle2) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "handle2")
}func main() {server := &http.Server{Addr:    "0.0.0.0:8888",Handler: nil, // 表示使用默认的多路复用器DefaultServerMux}// http.Handle 调用多路复用器的DefaultServerMux.Handle() 方法http.Handle("/handle1", &handle1{})http.Handle("/handle2", &handle2{})server.ListenAndServe()
}

03 自定义多路复用器.mp4

package mainimport ("fmt""net/http"
)// 定义多个处理器
type handle1 struct{}
type handle2 struct{}func (h *handle1) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "handle1")
}
func (h *handle2) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "handle2")
}func main() {// 自定义多路复用器mux := http.NewServeMux()mux.Handle("/handle1", &handle1{})mux.Handle("/handle2", &handle2{})server := &http.Server{Addr:    "0.0.0.0:8888",Handler: mux, // 表示使用默认的多路复用器DefaultServerMux}server.ListenAndServe()
}

04 配置读写超时时间.mp4

package mainimport ("fmt""net/http""time"
)// 定义多个处理器
type handle1 struct{}
type handle2 struct{}func (h *handle1) ServeHTTP(w http.ResponseWriter, r *http.Request) {time.Sleep(6 * time.Second)fmt.Fprintf(w, "handle1")
}
func (h *handle2) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "handle2")
}func main() {// 自定义多路复用器mux := http.NewServeMux()mux.Handle("/handle1", &handle1{})mux.Handle("/handle2", &handle2{})server := &http.Server{Addr:         "0.0.0.0:8888",Handler:      mux, // 表示使用默认的多路复用器DefaultServerMuxReadTimeout:  5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}

05 httprouter库的介绍和安装.mp4

06 httprouter的第一个使用案例.mp4

package mainimport ("fmt""github.com/julienschmidt/httprouter""net/http""time"
)func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {fmt.Fprint(w, "Welcome!\n")
}
func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}func main() {router := httprouter.New()router.GET("/", Index)router.GET("/hello/:name", Hello)server := &http.Server{Addr:         "0.0.0.0:8888",Handler:      router,ReadTimeout:  5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}

07 使用httprouter提取路径参数.mp4

package mainimport ("fmt""github.com/julienschmidt/httprouter""net/http""time"
)func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {fmt.Fprint(w, "Welcome!\n")
}
func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}func main() {router := httprouter.New()router.GET("/", Index)router.GET("/hello/:name", Hello)server := &http.Server{Addr:         "0.0.0.0:8888",Handler:      router,ReadTimeout:  5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}

08 复现浏览器跨域的问题.mp4

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>// const axios = require('axios');// 向给定ID的用户发起请求axios.get('http://127.0.0.1:8888/').then(function (response) {// 处理成功情况console.log(response);}).catch(function (error) {// 处理错误情况console.log(error);}).finally(function () {// 总是会执行});
</script>
</body>
</html>

09 使用httprouter分发二级域名.mp4

package mainimport ("github.com/julienschmidt/httprouter""log""net/http"
)// HostMap 域名映射字典
type HostMap map[string]http.Handlerfunc (hs HostMap) ServeHTTP(w http.ResponseWriter, r *http.Request) {//根据域名获取对应的Handler路由,然后调用处理(分发机制)if handler := hs[r.Host]; handler != nil {handler.ServeHTTP(w, r)} else {http.Error(w, "Forbidden", 403)}
}func main() {userRouter := httprouter.New()userRouter.GET("/", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {w.Write([]byte("sub1"))})dataRouter := httprouter.New()dataRouter.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {w.Write([]byte("sub2"))})//分别用于处理不同的二级域名hs := make(HostMap)hs["sub1.localhost:8888"] = userRouterhs["sub2.localhost:8888"] = dataRouterlog.Fatal(http.ListenAndServe(":8888", hs))
}

10 使用httprouter挂载静态文件目录.mp4

package mainimport ("github.com/julienschmidt/httprouter""log""net/http"
)func main() {router := httprouter.New()router.ServeFiles("/static/*filepath", http.Dir("c01_hello"))log.Fatal(http.ListenAndServe(":8888", router))
}

11 使用httprouter进行全局异常捕获.mp4

package mainimport ("fmt""github.com/julienschmidt/httprouter""log""net/http"
)func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {panic("error")
}func main() {router := httprouter.New()router.GET("/", Index)// 全局异常捕获router.PanicHandler = func(w http.ResponseWriter, r *http.Request, v interface{}) {w.WriteHeader(http.StatusInternalServerError)fmt.Fprintf(w, "全局异常捕获:%v", v)}log.Fatal(http.ListenAndServe(":8888", router))
}

12 将httprouter的代码下载到本地.mp4

13 使用本地化的httprouter.mp4

package mainimport ("fmt""github.com/zhangdapeng520/zdpgo_httprouter""net/http""time"
)func Index(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {fmt.Fprint(w, "Welcome!\n")
}func main() {router := zdpgo_httprouter.New()router.GET("/", Index)server := &http.Server{Addr:         "0.0.0.0:8888",Handler:      router,ReadTimeout:  5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}

14 给本地化的httprouter打标签.mp4

15 使用指定标签的本地化httprouter.mp4

16 带参数的自定义处理器.mp4

package mainimport ("fmt""net/http""time"
)type HelloHandler struct {Name string
}func (h HelloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello, %s!", h.Name)
}func main() {mux := http.NewServeMux()mux.Handle("/", HelloHandler{"张三"})server := &http.Server{Addr:         "0.0.0.0:8888",Handler:      mux,ReadTimeout:  5 * time.Second,WriteTimeout: 5 * time.Second,}server.ListenAndServe()
}

17 获取请求信息.mp4

package mainimport ("fmt""net/http""strings"
)func request(w http.ResponseWriter, r *http.Request) {fmt.Println("HTTP方法 method", r.Method)fmt.Println("RequestURI是被客户端发送到服务端的请求的请求行中未修改的请求URI RequestURI:", r.RequestURI)// URL类型,下方分别列出URL的各成员fmt.Println("URL_path", r.URL.Path)fmt.Println("URL_RawQuery", r.URL.RawQuery)fmt.Println("URL_Fragment", r.URL.Fragment)// 协议版本fmt.Println("proto", r.Proto)fmt.Println("protomajor", r.ProtoMajor)fmt.Println("protominor", r.ProtoMinor)// HTTP请求的头域for k, v := range r.Header {for _, vv := range v {fmt.Println("header key:" + k + "  value:" + vv)}}// 判断是否multipart方式isMultipart := falsefor _, v := range r.Header["Content-Type"] {if strings.Index(v, "multipart/form-data") != -1 {isMultipart = true}}// 解析bodyif isMultipart == true {r.ParseMultipartForm(128)fmt.Println("解析方式:ParseMultipartForm")} else {r.ParseForm()fmt.Println("解析方式:ParseForm")}// body内容长度fmt.Println("ContentLength", r.ContentLength)// 是否在回复请求后关闭连接fmt.Println("Close", r.Close)// HOStfmt.Println("host", r.Host)// 该请求的来源地址fmt.Println("RemoteAddr", r.RemoteAddr)fmt.Fprintf(w, "hello, let's go!") //这个写入到w的是输出到客户端的
}func main() {http.HandleFunc("/", request)http.ListenAndServe(":8888", nil)
}

代码截图

在这里插入图片描述

总结

本套教程主要讲解Go Web开发的基础知识,特别是讲解了httprouter的用法以及本地化方法,比附上了完整的实战代码。

通过本套课程,能帮你入门Go Web开发,写一些简单的Web程序。

如果您需要完整的源码,打赏20元即可。

人生苦短,我用Python,我是您身边的Python私教~

相关文章:

01 Go Web基础_20240728 课程笔记

概述 如果您没有Golang的基础&#xff0c;应该学习如下前置课程。 基础不好的同学每节课的代码最好配合视频进行阅读和学习&#xff0c;如果基础比较扎实&#xff0c;则阅读本教程巩固一下相关知识点即可&#xff0c;遇到不会的知识点再看视频。 视频课程 最近发现越来越多…...

嵌入式学习Day12---C语言提升

目录 一、指针数组 1.1.什么是指针数组 2.2. 格式 2.3.存储 2.4.与字符型二维数组相比 2.5.什么时候使用指针数组 2.6.练习 二、数组指针 2.1.什么是数组指针 2.2.格式 2.3.一维数组 2.3.特点 2.4.什么时候使用 三、指针和数组的关系 3.1.一维数组和指针 …...

6.6 使用dashboard商城搜索导入模板

本节重点介绍 : 模板商城中搜索模板导入模板修改模板 大盘模板商城地址 免费的 地址 https://grafana.com/grafana/dashboards 搜索模板技巧 详情 导入dashboard 两种导入模式 url导入id导入json文件导入 导入 node_exporter模板 https://grafana.com/grafana/dashboa…...

一文讲透useMemo和useCallback

在React项目中是经常会使用到useMemo&#xff0c;useCallBack的&#xff0c;这是两个优化性能的方法&#xff0c;那么useMemo&#xff0c;useCallBack到底是什么呢&#xff1f;什么时候用呢&#xff1f; 下面将给打击分享相关知识&#xff0c;希望对大家有所帮助同时欢迎讨论指…...

【环境变量】安装了一个软件,如何配置环境变量?

配置环境变量为啥&#xff1f; 方便地在任何文件夹下调用某一指定目录下的文件。 配置步骤 以jdk17为例。 1.打开环境变量配置页面 2.新建一个变量&#xff0c;变量名为JAVA_HOME&#xff0c;内容为jdk的path路径 3.打开path变量&#xff0c;新建一个%JAVA_HOME%\bin&#x…...

重生之我当程序猿外包

第一章 个人介绍与收入历程 我出生于1999年&#xff0c;在大四下学期进入了一家互联网公司实习。当时的实习工资是3500元&#xff0c;公司还提供住宿。作为一名实习生&#xff0c;这个工资足够支付生活开销&#xff0c;每个月还能给父母转1000元&#xff0c;自己留2500元用来吃…...

我想给 git 分支换一个名字,应该怎么做?

Git中重命名分支的操作步骤如下: 确保你在要重命名的分支上。可以使用git branch或git status命令查看当前所在分支[1][2]. 使用以下命令重命名当前分支: git branch -m new-branch-name例如,将当前分支重命名为"feature-xyz": git branch -m feature-xyz-m参数是&q…...

echarts多stack的legend点选

echarts支持点击legend&#xff0c;实现显示和隐藏legend对应的数据&#xff0c;具体就是option里series里,name为legend值的数据。 如果配置了多个stack&#xff0c;那么可能你可能设置了多组legend&#xff0c;你点选的是多个legend组中的某组中的一个&#xff0c;那么如果不…...

搭建自己的金融数据源和量化分析平台(四):自动化更新上市公司所属一级、二级行业以及股票上市状态

前面做了更新沪深交易所的上市股票列表的读取和更新&#xff0c;但一旦股票退市则需要在数据库里将该股票状态更新为退市&#xff0c;同时附上退市日期&#xff0c;将股票名更改为XX退。 此外深交所下载的xls解析出来是没有上市公司所属的二级行业的&#xff0c;因此还需要建立…...

科创板重启IPO上会!募投审核新方向?思看科技等优化募投项目

撰稿 | 多客 来源 | 贝多财经 根据上交所项目审核动态最新公告&#xff0c;思看科技&#xff08;杭州&#xff09;股份有限公司&#xff08;简称“思看科技”&#xff09;将于8月2日上会&#xff0c;标志着时隔50天后科创板重新迎来首家上会企业&#xff0c;也标志着思看科技…...

深入解析损失函数:从基础概念到YOLOv8的应用

深入解析损失函数&#xff1a;从基础概念到YOLOv8的应用 在机器学习和深度学习中&#xff0c;损失函数是至关重要的组件&#xff0c;它们衡量模型的预测值与真实值之间的差距&#xff0c;从而指导模型的优化过程。本文将详细探讨损失函数的基本概念&#xff0c;及其在YOLOv8中…...

2.11.ResNet

ResNet 动机&#xff1a;我们总是想加更多层&#xff0c;但加更多层并不总是能改进精度 可以看出F1到F6模型越来越大&#xff0c;但F6距离最优解却总变远了&#xff0c;反而效果不好&#xff0c;通俗的来说就是学偏了&#xff0c;实际上我们希望是这样的&#xff1a; ​ 更大…...

GitLab添加TortoiseGIT生成SSH Key

文章目录 前言一、PuTTYgen二、GitLab 前言 GitLab是一个用于托管代码仓库和项目管理的Web平台&#xff0c;公司搭建自己的gitlab来管理代码&#xff0c;我们在clone代码的时候可以选择http协议&#xff0c;也可以选择ssh协议来拉取代码。 SSH (Secure Shell)是一种通过网络进…...

20240729 大模型评测

参考&#xff1a; MMBench&#xff1a;基于ChatGPT的全方位多模能力评测体系_哔哩哔哩_bilibili https://en.wikipedia.org/wiki/Levenshtein_distance cider: https://zhuanlan.zhihu.com/p/698643372 GitHub - open-compass/opencompass: OpenCompass is an LLM evalua…...

基于微信小程序的校园警务系统/校园安全管理系统/校园出入管理系统

摘要 伴随着社会以及科学技术的发展&#xff0c;小程序已经渗透在人们的身边&#xff0c;小程序慢慢的变成了人们的生活必不可少的一部分&#xff0c;紧接着网络飞速的发展&#xff0c;小程序这一名词已不陌生&#xff0c;越来越多的学校机构等都会定制一款属于自己个性化的小程…...

达梦数据库归档介绍

一、什么是归档 数据库归档是一种数据管理策略&#xff0c;它涉及将旧的、不经常访问的数据移动到一个单独的存储设备&#xff0c;以便在需要时可以检索&#xff0c;同时保持数据库的性能和效率。 归档的主要目标是为了释放数据库中的空间&#xff0c;以便更有效地利用高性能…...

OpenAI推出AI搜索引擎SearchGPT

OpenAI推出AI搜索引擎SearchGPT 据英国《卫报》和美国消费者新闻与商业频道等媒体报道&#xff0c;7月25日&#xff0c;OpenAI宣布正在测试一款名为SearchGPT的全新人工智能&#xff08;AI&#xff09;搜索工具。该工具能够实时访问互联网信息&#xff0c;旨在为用户提供更具时…...

elementplus菜单组件的那些事

在使用 elementplus 的菜单组件时&#xff0c;我发现有很多东西是官方没有提到但是需要注意的点 1. 菜单组件右侧会有一个边框 设置css .el-menu {border: 0 !important; } 2. 使用其他的 icon 文字内容一定要写在 这个 名字为 title 的插槽中 <el-menu-itemv-for"it…...

【VSCode实战】Golang无法跳转问题竟是如此简单

上一讲【VSCode实战】Go插件依赖无法安装 – 经云的清净小站 (skycreator.top)&#xff0c;开头说到了在VSCode中Golang无法跳转的问题&#xff0c;但文章的最后也没给出解决方案&#xff0c;只解决了安装Go插件的依赖问题。 解决了插件依赖问题&#xff0c;无法跳转的问题也离…...

three.js中加载ply格式的文件,并使用tween.js插件按照json姿态文件运动

先贴一下文件地址&#xff1a; aa.ply 文件&#xff1a; https://download.csdn.net/download/yinge0508/89595650?spm1001.2014.3001.5501 new.json https://download.csdn.net/download/yinge0508/89595641?spm1001.2014.3001.5501 代码: <template><div>&…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...