Go语言笔记[实现一个Web框架实战]——EzWeb框架(一)

一、Golang中的net/http标准库如何处理一个请求

func main() {
http.HandleFunc("/", handler)
http.HandleFunc("/count", counter)
log.Fatal(http.ListenAndServe("localhost:9090", nil))
} func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
}

标准库中实现了监听,映射路由,和解析http报文。

浏览器的请求,http.ListenAndServe方法中,第一个参数是监听地址响,第二个参数代表处理所有的HTTP请求的实例,nil代表使用标准库中的实例处理。

我们通过第二个参数,转入到我们的实例,这样所有的HTTP请求就都交给了我们的实例来处理。

二、实现http.Handler接口

/*
@Time : 2021/8/5 下午4:08
@Author : mrxuexi
@File : main
@Software: GoLand
*/
package main import (
"fmt"
"log"
"net/http"
) type Engine struct {}
/**
* @Description:
对Engine结构体的ServeHttp方法实现。ServeHTTP是Handler接口中的一个方法,在这里我们对这个方法进行实现,放入到我们的Engine中。这里就用上了我们的自定义方法来处理请求。
* @receiver engine
* @param w http.ResponseWriter(通过该ResponseWriter构造针对该请求的响应)
* @param req *http.Request(Request中包括了发送来的HTTP请求的全部信息)
*/
func (engine *Engine)ServeHTTP(w http.ResponseWriter, req *http.Request) {
switch req.URL.Path {
case "/":
fmt.Fprintf(w,"URL.Path = %q\n", req.URL.Path)
case "/hello":
for k, v := range req.Header {
fmt.Fprintf(w,"Header[%q] = %q \n", k, v)
}
default:
fmt.Fprintf(w,"404 NOT FOUND: %s\n", req.URL)
}
} func main() {
engine := new(Engine)
//此处后者的参数填入engine,让请求交由我们实现的engine实例来处理
log.Fatal(http.ListenAndServe(":9090",engine))
}

三、实现简单的GET,POST方法,实现框架简单原型

设计自己的Engine结构体,然后将原来启动web项目的

   log.Fatal(http.ListenAndServe(":9090",engine))

封装成Run(addr),并将第二个参数的默认实例,直接写为我们的engine实例。

func (engine *Engine) Run(addr string) (err error) {
return http.ListenAndServe(addr, engine)
}

这里engine涉及到一个转换,实现了接口方法的struct转换为接口类型

我们要实现的GET,POST方法。作用是,将路由和方法,注册进来,然后在监听的时候进行查找和处理。

这里设计一个router放入到我们的Engine结构体中:

// Engine 实现了"net/http"标准库中的 Handler 接口中的ServeHTTP方法
type Engine struct {
//用于存储路由处理方法
//key是方法类型加路径,value是用户的处理方法
router map[string]HandlerFunc
}

我们的GET和POST方法就是这样实现的,调用addRoute方法,将路由和响应方法存入到router中:

// GET 实现的是Engine的处理GET请求的方法,注册到router中
func (engine *Engine) GET(path string, handler HandlerFunc) {
engine.addRoute("GET", path, handler)
} // POST 同上
func (engine *Engine) POST(path string, handler HandlerFunc) {
engine.addRoute("POST", path, handler)
}

这里就是addRoute方法,method-path作为key,handler作为value

// Engine 中 addRoute 方法,在 router map[string]HandlerFunc 中存入对应处理方法
//存入形式为例如:{ "GET-/index" : 定义的处理方法 }engine
func (engine *Engine) addRoute(method string, path string, handler HandlerFunc) {
key := method + "-" + path
engine.router[key] = handler
}

我们再重写Handler接口中的ServeHTTP方法,通过req请求的路由查找router中注册的方法执行。

// ServeHTTP 方法的实现,用于实现处理HTTP请求
// 先解析req对应传入的路径,查找router中,如果有相应的处理方法,则执行处理方法,如果没有则返回找不到的提示
// 来自Handler接口
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
key := req.Method + "-" + req.URL.Path
//根据请求req中的数据,从router中取出对应的方法
if handler, ok := engine.router[key]; ok {
handler(w, req)
} else {
fmt.Fprintf(w, "could not find the route: %s\n", req.URL)
}
}

雏形的全部源码:

/*
@Time : 2021/8/16 下午4:03
@Author : Mrxuexi
@File : Ez
@Software: GoLand
*/ package Ez import (
"fmt"
"net/http"
) // HandlerFunc 是Ez框架中定义的对请求的响应处理方法,默认传入这两个参数,针对http请求处理
type HandlerFunc func(http.ResponseWriter, *http.Request) // Engine 实现了"net/http"标准库中的 Handler 接口中的ServeHTTP方法
type Engine struct {
//用于存储路由处理方法
//key是方法类型加路径,value是用户的处理方法
router map[string]HandlerFunc
} // ServeHTTP 方法的实现,用于实现处理HTTP请求
// 先解析req对应传入的路径,查找router中,如果有相应的处理方法,则执行处理方法,如果没有则返回找不到的提示
// 来自Handler接口
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
key := req.Method + "-" + req.URL.Path
//根据请求req中的数据,从router中取出对应的方法
if handler, ok := engine.router[key]; ok {
handler(w, req)
} else {
fmt.Fprintf(w, "could not find the route: %s\n", req.URL)
}
} // New 是Ez.Engine的构造函数
func New() *Engine {
return &Engine{router: make(map[string]HandlerFunc)}
} // Engine 中 addRoute 方法,在 router map[string]HandlerFunc 中存入对应处理方法
//存入形式为例如:{ "GET-/index" : 定义的处理方法 }engine
func (engine *Engine) addRoute(method string, path string, handler HandlerFunc) {
key := method + "-" + path
engine.router[key] = handler
} // GET 实现的是Engine的处理GET请求的方法,注册到router中
func (engine *Engine) GET(path string, handler HandlerFunc) {
engine.addRoute("GET", path, handler)
} // POST 同上
func (engine *Engine) POST(path string, handler HandlerFunc) {
engine.addRoute("POST", path, handler)
} // Run 用于启动服务,直接制定用该路由的engine
func (engine *Engine) Run(addr string) (err error) {
return http.ListenAndServe(addr, engine)
}

尝试使用:

/*
@Time : 2021/8/16 下午4:01
@Author : mrxuexi
@File : main
@Software: GoLand
*/
package main import (
"Ez"
"fmt"
"net/http"
)
func main() {
r := Ez.New()
r.GET("/hello", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w,"Hello")
})
r.Run(":9090")
}

成功!

后续我们继续完善内容

参考:

[1]: https://github.com/geektutu/7days-golang/tree/master/gee-web ""gee""

[2]: https://github.com/gin-gonic/gin ""gin""

Go语言笔记[实现一个Web框架实战]——EzWeb框架(一)的更多相关文章

  1. 手把手和你一起实现一个Web框架实战——EzWeb框架(二)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(二)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 上一篇文章我们实现了框架的雏形,基本地 ...

  2. 手把手和你一起实现一个Web框架实战——EzWeb框架(三)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(三)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo3 这一篇文章 ...

  3. 手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(四)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 这一篇文章主要实现路由组功能.实现路由 ...

  4. 手把手和你一起实现一个Web框架实战——EzWeb框架(五)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(五)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo5 中间件实现 ...

  5. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

  6. 【转载】ASP.NET MVC Web API 学习笔记---第一个Web API程序

    1. Web API简单说明 近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过 ...

  7. ASP.NET MVC Web API 学习笔记---第一个Web API程序【转】

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html 1. Web API简单说明 近来很多大型的平台都公开了Web API. ...

  8. ASP.NET MVC Web API 学习笔记---第一个Web API程序---近来很多大型的平台都公开了Web API

    1. Web API简单说明 近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过 ...

  9. MyBatis整合Spring+SpringMVC搭建一个web项目(SSM框架)

    本文讲解如何搭建一个SSM架构的web站点 [工具] IDEA.SqlYog.Maven [简述] 该项目由3个模块组成:dao(数据访问层).service(业务处理层).web(表现层) dao层 ...

随机推荐

  1. iOS工程师如何恍然大悟?

    聊聊行情?为什么总有人在乎旁人的看法而忽略自己的初衷? 虽然iOS开发市场说不上好但也绝不算坏,想没想过那些煽风点火说iOS不行的人在做什么? 真的转行从头开始? 错.大错特错! 在劝退你的同时他们会 ...

  2. 登录华科校园网,我用Socket

    登录华科校园网,我用Socket 导语: 找一个华科学生问一问,学校的网络怎么样?得到的大多数是负面回答.其实不论是从覆盖区域.网络稳定性.还是速度来说,华科做的都还是可以的(24:00断网除外).可 ...

  3. 『动善时』JMeter基础 — 53、JMeter集合点功能的使用

    目录 1.集合点介绍 2.同步定时器界面介绍 3.集合点的使用 (1)测试计划内包含的元件 (2)线程组元件内容 (3)HTTP请求组件内容 (4)同步定时器内容 (5)运行脚本查看结果 4.集合点设 ...

  4. Docker单机网络上

    前言 Docker系列文章: 此篇是Docker系列的第六篇,大家一定要按照我做的Demo都手敲一遍,印象会更加深刻的,加油! 为什么要学习Docker Docker基本概念 Docker镜像基本原理 ...

  5. Python装饰器-给你的咖啡加点料

    今天你的咖啡加糖了吗? 让我们通过一个简单的例子来引出装饰器的概念及用法.在引出装饰器之前,我们先来了解一下函数的概念. 一.函数回顾 1.在python中函数是一等公民,函数也是对象.我们可以把函数 ...

  6. SpringMVC(10)实现注解式权限验证

    在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码精简且便于维护呢?这就是本篇要讲的内容->异 ...

  7. cobbler安装4个报错汇总及解决方法:ImportError

    安装完,检查cobbler:cobbler check发现这个问题ImportError: No module named yaml 具体报错如下: [root@www localdisk]# cob ...

  8. 「CF568C」 New Language

    「CF568C」 New Language 一眼 \(\texttt{2-SAT}\) . 然后不会了. 又看了一会儿,然后发现只要我们确定每个位置大于字典序的两种最小的字母是啥,然后按位贪心,这个问 ...

  9. python 动态指定header获取网页源代码的函数

    import random import requests def get_htmla(url): aui=0 while aui==0: try: header={'User-Agent':'Moz ...

  10. 简单梳理 ES6 函数

    箭头函数 箭头函数提供了一种更加简洁的函数书写方式.基本语法是 参数 => 函数体 基本用法: var f = v => v; //等价于 var f = function(a){ ret ...