概述
如果您没有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 main
import (
"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 main
import (
"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 main
import (
"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 main
import (
"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, // 表示使用默认的多路复用器DefaultServerMux
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
}
server.ListenAndServe()
}
05 httprouter库的介绍和安装.mp4
06 httprouter的第一个使用案例.mp4
package main
import (
"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 main
import (
"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 main
import (
"github.com/julienschmidt/httprouter"
"log"
"net/http"
)
// HostMap 域名映射字典
type HostMap map[string]http.Handler
func (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"] = userRouter
hs["sub2.localhost:8888"] = dataRouter
log.Fatal(http.ListenAndServe(":8888", hs))
}
10 使用httprouter挂载静态文件目录.mp4
package main
import (
"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 main
import (
"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 main
import (
"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 main
import (
"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 main
import (
"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 := false
for _, v := range r.Header["Content-Type"] {
if strings.Index(v, "multipart/form-data") != -1 {
isMultipart = true
}
}
// 解析body
if 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)
// HOSt
fmt.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私教~