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的基础,应该学习如下前置课程。 基础不好的同学每节课的代码最好配合视频进行阅读和学习,如果基础比较扎实,则阅读本教程巩固一下相关知识点即可,遇到不会的知识点再看视频。 视频课程 最近发现越来越多…...

嵌入式学习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,useCallBack的,这是两个优化性能的方法,那么useMemo,useCallBack到底是什么呢?什么时候用呢? 下面将给打击分享相关知识,希望对大家有所帮助同时欢迎讨论指…...
【环境变量】安装了一个软件,如何配置环境变量?
配置环境变量为啥? 方便地在任何文件夹下调用某一指定目录下的文件。 配置步骤 以jdk17为例。 1.打开环境变量配置页面 2.新建一个变量,变量名为JAVA_HOME,内容为jdk的path路径 3.打开path变量,新建一个%JAVA_HOME%\bin&#x…...

重生之我当程序猿外包
第一章 个人介绍与收入历程 我出生于1999年,在大四下学期进入了一家互联网公司实习。当时的实习工资是3500元,公司还提供住宿。作为一名实习生,这个工资足够支付生活开销,每个月还能给父母转1000元,自己留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,实现显示和隐藏legend对应的数据,具体就是option里series里,name为legend值的数据。 如果配置了多个stack,那么可能你可能设置了多组legend,你点选的是多个legend组中的某组中的一个,那么如果不…...

搭建自己的金融数据源和量化分析平台(四):自动化更新上市公司所属一级、二级行业以及股票上市状态
前面做了更新沪深交易所的上市股票列表的读取和更新,但一旦股票退市则需要在数据库里将该股票状态更新为退市,同时附上退市日期,将股票名更改为XX退。 此外深交所下载的xls解析出来是没有上市公司所属的二级行业的,因此还需要建立…...

科创板重启IPO上会!募投审核新方向?思看科技等优化募投项目
撰稿 | 多客 来源 | 贝多财经 根据上交所项目审核动态最新公告,思看科技(杭州)股份有限公司(简称“思看科技”)将于8月2日上会,标志着时隔50天后科创板重新迎来首家上会企业,也标志着思看科技…...
深入解析损失函数:从基础概念到YOLOv8的应用
深入解析损失函数:从基础概念到YOLOv8的应用 在机器学习和深度学习中,损失函数是至关重要的组件,它们衡量模型的预测值与真实值之间的差距,从而指导模型的优化过程。本文将详细探讨损失函数的基本概念,及其在YOLOv8中…...

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

GitLab添加TortoiseGIT生成SSH Key
文章目录 前言一、PuTTYgen二、GitLab 前言 GitLab是一个用于托管代码仓库和项目管理的Web平台,公司搭建自己的gitlab来管理代码,我们在clone代码的时候可以选择http协议,也可以选择ssh协议来拉取代码。 SSH (Secure Shell)是一种通过网络进…...
20240729 大模型评测
参考: MMBench:基于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…...

基于微信小程序的校园警务系统/校园安全管理系统/校园出入管理系统
摘要 伴随着社会以及科学技术的发展,小程序已经渗透在人们的身边,小程序慢慢的变成了人们的生活必不可少的一部分,紧接着网络飞速的发展,小程序这一名词已不陌生,越来越多的学校机构等都会定制一款属于自己个性化的小程…...

达梦数据库归档介绍
一、什么是归档 数据库归档是一种数据管理策略,它涉及将旧的、不经常访问的数据移动到一个单独的存储设备,以便在需要时可以检索,同时保持数据库的性能和效率。 归档的主要目标是为了释放数据库中的空间,以便更有效地利用高性能…...
OpenAI推出AI搜索引擎SearchGPT
OpenAI推出AI搜索引擎SearchGPT 据英国《卫报》和美国消费者新闻与商业频道等媒体报道,7月25日,OpenAI宣布正在测试一款名为SearchGPT的全新人工智能(AI)搜索工具。该工具能够实时访问互联网信息,旨在为用户提供更具时…...
elementplus菜单组件的那些事
在使用 elementplus 的菜单组件时,我发现有很多东西是官方没有提到但是需要注意的点 1. 菜单组件右侧会有一个边框 设置css .el-menu {border: 0 !important; } 2. 使用其他的 icon 文字内容一定要写在 这个 名字为 title 的插槽中 <el-menu-itemv-for"it…...

【VSCode实战】Golang无法跳转问题竟是如此简单
上一讲【VSCode实战】Go插件依赖无法安装 – 经云的清净小站 (skycreator.top),开头说到了在VSCode中Golang无法跳转的问题,但文章的最后也没给出解决方案,只解决了安装Go插件的依赖问题。 解决了插件依赖问题,无法跳转的问题也离…...
three.js中加载ply格式的文件,并使用tween.js插件按照json姿态文件运动
先贴一下文件地址: aa.ply 文件: 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>&…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...