从零实现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...

相关推荐
魔尔助理顾问3 小时前
一个简洁高效的Flask用户管理示例
后端·python·flask
李长渊哦6 小时前
使用Druid连接池优化Spring Boot应用中的数据库连接
数据库·spring boot·后端
web135085886356 小时前
【Spring Boot】Spring AOP动态代理,以及静态代理
spring boot·后端·spring
nbsaas-boot7 小时前
Go 自动升级依赖版本
开发语言·后端·golang
zzyh1234568 小时前
springcloud的组件及作用
后端·spring·spring cloud
尚学教辅学习资料8 小时前
基于SpringBoot的图书借阅小程序+LW参考示例
spring boot·后端·小程序·java毕设·图书借阅
山海不说话8 小时前
从零搭建微服务项目Base(第5章——SpringBoot项目LogBack日志配置+Feign使用)
spring boot·后端·spring·spring cloud·微服务·logback
databook9 小时前
『Python底层原理』--CPython的变量实现机制
后端·python
初尘屿风9 小时前
小程序类毕业设计选题题目推荐 (29)
spring boot·后端·学习·微信·小程序·课程设计
JavaGuide10 小时前
武汉小米 Java 岗位一二面校招面经
java·后端