day 2| 上下文Context

再次来解释一下上下文,我也忘了,问下chatgpt

上下文在 Go Web 开发中是指与当前 HTTP 请求相关的环境信息,它提供了更多的控制和功能来处理 HTTP 请求和响应。也就是对get和POST方法的强化

对于处理 HTML 或 JSON 等响应内容,上下文同样是一个重要的组成部分。在处理 HTTP 请求时,上下文不仅包含了与请求相关的信息,还包括了与响应相关的信息。

本节需要完成的 :

  • 将路由独立出来,方便之后增强

  • 设计上下文(CONTEXXT),封装Request和Response,提供对JSON,HTNL等返回类型的支持

最终成果展示一下:

func main() {
    r := gee.New()
    r.GET("/", func(c *gee.Context) {
        c.HTML(http.StatusOK, "<h1>Hello Gee</h1>")
    })
    r.GET("/hello", func(c *gee.Context) {
        // expect /hello?name=geektutu
        c.String(http.StatusOK, "hello %s, you're at %s\n", c.Query("name"), c.Path)
    })
​
    r.POST("/login", func(c *gee.Context) {
        c.JSON(http.StatusOK, gee.H{
            "username": c.PostForm("username"),
            "password": c.PostForm("password"),
        })
    })
​
    r.Run(":9999")
}

可以发现GET函数的第二个参数变成了gee.Context,提供了查询 和 解析表单的功能

gee.Context封装了HTML/String/JSON函数,能够快速构造HTTP响应

设计Context

必要性:

对于Web服务来说,每次我们都需要进行响应,http.ResponseWriter,但是每次我们都要考虑消息头(Header)和消息体(Body),但是Header又包含了状态码(StatusCode),消息类型(ContentType)等几乎每次请求都需要设置的信息,对于这样 的信息我们往往需要对这些信息进行有效的封装

封装前:

obj = map[string]interface{}{
    "name": "geektutu",
    "password": "1234",
}
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(), 500)
}

封装后:

c.JSON(http.StatusOK, gee.H{
    "username": c.PostForm("username"),
    "password": c.PostForm("password"),
}

其实也就是这对第一段代码进行了封装,将

而且较容易出错

2.针对使用场景:

对于框架来说,还需要支撑额外的功能,例如:/hello/:name 参数:name放在哪里

Context随着每个请求的出现而产生,请求的结束而销毁,和当前请求相关的信息都应用Context承载

主要看这个命令行输入

-X POST是cURL命令的一个选项,用于指定HTTP请求的方法

-d选项发送了表单数据

小伙伴们可以进行一下调试,然后拿张纸看进行到哪一步了

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, req *http.Request) *Context {
    return &Context{
        Writer: w,
        /*writer 有头部响应() 还有 状态码*/
        Req:    req,
        Path:   req.URL.Path,
        Method: req.Method,  //我们从request中自动提取响应的method
        //在我们实验的时候还是会指明我们使用的方法
        //Get一般是在URL后面
    }
}
//访问Query and PostForm 的方法
func (c *Context) PostForm(key string) string {
    return c.Req.FormValue(key)
}
​
func (c *Context) Query(key string) string {
    return c.Req.URL.Query().Get(key)
}
​
​
func (c *Context) Status(code int) {
    c.StatusCode = code
    c.Writer.WriteHeader(code)
}
​
func (c *Context) SetHeader(key string, value string) {
    c.Writer.Header().Set(key, value)
}
​
/*
快速构造String,Data,JSON,HTML响应
*/
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...)))
}
​
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(), 500)
    }
}
​
func (c *Context) Data(code int, data []byte) {
    c.Status(code)
    c.Writer.Write(data)
}
​
func (c *Context) HTML(code int, html string) {
    c.SetHeader("Content-Type", "text/html")
    c.Status(code)
    c.Writer.Write([]byte(html))
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值