从零实现gin day01

前言

刚开始学go想着不能一直输入,得有点输出才能记得住学的东西,故决定写一些学习笔记来记录自己的学习历程.

知识点

  • 使用go开启TCP服务
  • 使用go发送http请求
  • 实现TCP监听回调服务

http请求封装

怎么用go开启TCP服务

go 复制代码
package main  
  
import (  
    "fmt"  
    "log"  
    "net/http"  
)  
  
func main() {  
    http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {  
    writer.Write([]byte(fmt.Sprintf("hello %s\n", "cc")))  
})  
  
    log.Fatal(http.ListenAndServe(":7999", nil))  
}

http.HandleFunc 添加一个路由,添加了路由我们怎么去监听这个路由是否正确呢?http.ListenAndServe中的第二个参数就派上用场了,从源码中可以看到,在开启TCP监听端口之后会回调一个handler requests这个Handler是一个接口,里面有一个ServeHTTP方法,所以只要实现了这个方法的都可以作为参数传给ListenAndServe

监听源码

go 复制代码
type Handler interface {  
    ServeHTTP(ResponseWriter, *Request)  
}
// ListenAndServe listens on the TCP network address addr and then calls  
// Serve with handler to handle requests on incoming connections.  
// Accepted connections are configured to enable TCP keep-alives.
// ListenAndServe always returns a non-nil error.  
func ListenAndServe(addr string, handler Handler) error {  
    server := &Server{Addr: addr, Handler: handler}  
    return server.ListenAndServe()  
}

实现

go 复制代码
package main  
  
import (  
    "fmt"  
    "net/http"  
)  
  
type Engine struct {  
}  
  
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {  
    path := r.URL.Path  
    if path == "/" {  
        fmt.Fprint(w, "index")  
    } else if path == "/hello" {  
        fmt.Fprint(w, "hello world")  
    } else {  
        fmt.Fprint(w, "404")  
    }  
}

那么main函数中的ListenAndServe就可以直接使用这个作为回调方法传入.

go 复制代码
func main() {  
    http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {  
        writer.Write([]byte(fmt.Sprintf("hello %s\n", "cc")))  
    })   
    e := new(Engine)  
    log.Fatal(http.ListenAndServe(":7999", e))  
}

我们使用postman进行测试,都出现了我们预期的结果,但是在http.HandleFunc中写的匿名函数并没有执行,要想这个匿名函数执行就要把其放到ServeHTTP中去.所以我们可以进一步改造.

给Engine添加router,封装Post,Get,Run方法

go 复制代码
package main  
  
import (  
    "fmt"  
    "net/http"  
)  
  
type HandleFunc http.HandlerFunc  
  
type Engine struct {  
    router map[string]HandleFunc  
}  
  
func newEngine() *Engine {  
    return &Engine{router: make(map[string]HandleFunc)}  
}  
  
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {  
    key := r.Method + "-" + r.URL.Path  
    if h, ok := e.router[key]; ok {  
        h(w, r)  
    } else {  
        w.WriteHeader(http.StatusNotFound)
        fmt.Fprint(w, "404")  
    }  
}  
func (e *Engine) AddRouter(method string, path string, handle HandleFunc) {  
    key := method + "-" + path  
    e.router[key] = handle  
}  
func (e *Engine) Post(path string, handle HandleFunc) {  
    e.AddRouter("POST", path, handle)  
}  
func (e *Engine) Get(path string, handle HandleFunc) {  
    e.AddRouter("GET", path, handle)  
}  
  
func (e *Engine) Run(addr string) (err error) {  
    return http.ListenAndServe(addr, e)  
}

我们给Engine添加了一个router变量,类型为map[string]HandleFunc这样就能通过key找到其对应的HandleFunc方法,从而执行.

总结

本章我们完成了TCP服务监听的封装,并能通过Post,Get添加路由请求,并且能对不存在的路由进行提示.

更多详情连接:geektutu.com/post/gee.ht...

相关推荐
Iced_Sheep1 小时前
干掉 if else 之策略模式
后端·设计模式
XINGTECODE1 小时前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
程序猿进阶1 小时前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺1 小时前
Spring Boot框架Starter组件整理
java·spring boot·后端
凡人的AI工具箱2 小时前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
先天牛马圣体2 小时前
如何提升大型AI模型的智能水平
后端
java亮小白19972 小时前
Spring循环依赖如何解决的?
java·后端·spring
2301_811274312 小时前
大数据基于Spring Boot的化妆品推荐系统的设计与实现
大数据·spring boot·后端
草莓base3 小时前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring
Ljw...3 小时前
表的增删改查(MySQL)
数据库·后端·mysql·表的增删查改