From 44895b8fe92d0e1fc5ff3e00d51f8bddd05790fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=AC=E5=AD=A4=E4=BC=B6=E4=BF=9C?= <1184662350@qq.com> Date: Thu, 26 Jan 2023 23:26:32 +0800 Subject: [PATCH] =?UTF-8?q?7Days=20Gee=20Day2=20Context=20=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- day2/gee/context.go | 82 +++++++++++++++++++++++++++++++++++++++++++++ day2/gee/gee.go | 40 ++++++++++++++++++++++ day2/gee/go.mod | 3 ++ day2/gee/router.go | 27 +++++++++++++++ day2/go.mod | 10 ++++++ day2/go.work | 6 ++++ day2/main.go | 39 +++++++++++++++++++++ 7 files changed, 207 insertions(+) create mode 100644 day2/gee/context.go create mode 100644 day2/gee/gee.go create mode 100644 day2/gee/go.mod create mode 100644 day2/gee/router.go create mode 100644 day2/go.mod create mode 100644 day2/go.work create mode 100644 day2/main.go diff --git a/day2/gee/context.go b/day2/gee/context.go new file mode 100644 index 0000000..7186d50 --- /dev/null +++ b/day2/gee/context.go @@ -0,0 +1,82 @@ +package gee + +import ( + "encoding/json" + "fmt" + "net/http" +) + +type H map[string]interface{} + +type Context struct { + // origin objects 源对象 + Writer http.ResponseWriter + Req *http.Request + // request info 请求信息 + Path string + Method string + // response info 响应信息 + StatusCode int +} + +func newContext(w http.ResponseWriter, r *http.Request) *Context { + return &Context{ + Writer: w, + Req: r, + Path: r.URL.Path, + Method: r.Method, + } +} + +// PostForm 返回请求参数的值 +func (c *Context) PostForm(key string) string { + return c.Req.FormValue(key) +} + +// Query 返回请求参数的值 +func (c *Context) Query(key string) string { + // Query方法解析RawQuery字段并返回其表示的Values类型键值对map。 + // Get会获取key对应的值集的第一个值。如果没有对应key的值集会返回空字符串。 + return c.Req.URL.Query().Get(key) +} + +// Status 设置响应状态码 +func (c *Context) Status(code int) { + c.StatusCode = code + c.Writer.WriteHeader(code) +} + +// SetHeader 设置响应头 +func (c *Context) SetHeader(key string, value string) { + c.Writer.Header().Set(key, value) +} + +// String 设置 string 类型的响应体 +func (c *Context) String(code int, format string, values ...interface{}) { + c.SetHeader("Content-Type", "text/plain") + c.Status(code) + _, _ = c.Writer.Write([]byte(fmt.Sprintf(format, values...))) +} + +// Json 设置 json 类型的响应体 +func (c *Context) Json(code int, obj interface{}) { + c.SetHeader("Content-Type", "application/json") + c.Status(code) + encoder := json.NewEncoder(c.Writer) + if err := encoder.Encode(obj); err != nil { + http.Error(c.Writer, err.Error(), http.StatusInternalServerError) + } +} + +// Data 设置 data 类型的响应体 +func (c *Context) Data(code int, data []byte) { + c.Status(code) + _, _ = c.Writer.Write(data) +} + +// Html 设置 html 类型的响应体 +func (c *Context) Html(code int, html string) { + c.SetHeader("Content-Type", "text/html") + c.Status(code) + _, _ = c.Writer.Write([]byte(html)) +} diff --git a/day2/gee/gee.go b/day2/gee/gee.go new file mode 100644 index 0000000..05bdf71 --- /dev/null +++ b/day2/gee/gee.go @@ -0,0 +1,40 @@ +package gee + +import "net/http" + +type HandlerFunc func(*Context) + +type Engine struct { + router *router +} + +// New 实例化Engine +func New() *Engine { + return &Engine{router: newRouter()} +} + +// addRoute 添加路由规则 +func (engine *Engine) addRoute(method string, pattern string, handler HandlerFunc) { + engine.router.addRoute(method, pattern, handler) +} + +// GET 添加GET路由规则 +func (engine *Engine) GET(pattern string, handler HandlerFunc) { + engine.addRoute("GET", pattern, handler) +} + +// POST 添加POST路由规则 +func (engine *Engine) POST(pattern string, handler HandlerFunc) { + engine.addRoute("POST", pattern, handler) +} + +// Run 启动服务 +func (engine *Engine) Run(addr string) (err error) { + return http.ListenAndServe(addr, engine) +} + +// ServeHTTP 实现了ServeHTTP接口 +func (engine *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) { + c := newContext(w, r) + engine.router.handle(c) +} diff --git a/day2/gee/go.mod b/day2/gee/go.mod new file mode 100644 index 0000000..66c69e9 --- /dev/null +++ b/day2/gee/go.mod @@ -0,0 +1,3 @@ +module gee + +go 1.19 \ No newline at end of file diff --git a/day2/gee/router.go b/day2/gee/router.go new file mode 100644 index 0000000..7edb24c --- /dev/null +++ b/day2/gee/router.go @@ -0,0 +1,27 @@ +package gee + +import "net/http" + +type router struct { + handlers map[string]HandlerFunc +} + +func newRouter() *router { + return &router{handlers: make(map[string]HandlerFunc)} +} + +// addRoute 添加路由规则 +func (r *router) addRoute(method string, pattern string, handler HandlerFunc) { + key := method + "-" + pattern + r.handlers[key] = handler +} + +// handle 路由匹配 +func (r *router) handle(c *Context) { + key := c.Method + "-" + c.Path + if handler, ok := r.handlers[key]; ok { + handler(c) + } else { + c.String(http.StatusNotFound, "404 NOT FOUND: %s\n", c.Path) + } +} diff --git a/day2/go.mod b/day2/go.mod new file mode 100644 index 0000000..9ec1b18 --- /dev/null +++ b/day2/go.mod @@ -0,0 +1,10 @@ +module git.srv.ink/7DaysGee/Day2 + +require ( + gee v0.0.2 +) + +replace ( + gee => ./gee +) +go 1.19 \ No newline at end of file diff --git a/day2/go.work b/day2/go.work new file mode 100644 index 0000000..2897683 --- /dev/null +++ b/day2/go.work @@ -0,0 +1,6 @@ +go 1.19 + +use ( + . + gee +) \ No newline at end of file diff --git a/day2/main.go b/day2/main.go new file mode 100644 index 0000000..dc39bdf --- /dev/null +++ b/day2/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "gee" + "net/http" +) + +func main() { + + //// 封装前 + //obj := map[string]interface{}{} + //obj["name"] = "dug" + //obj["age"] = 18 + //http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // w.Header().Set("Content-Type", "application/json") + // w.WriteHeader(http.StatusOK) + // encoder := json.NewEncoder(w) + // if err := encoder.Encode(obj); err != nil { + // http.Error(w, err.Error(), http.StatusInternalServerError) + // } + //}) + //_ = http.ListenAndServe(":9000", nil) + + r := gee.New() + r.GET("/", func(c *gee.Context) { + c.Html(http.StatusOK, "