学习资料来自:GitHub - geektutu/7days-golang: 7 days golang programs from scratch (web framework Gee, distributed cache GeeCache, object relational mapping ORM framework GeeORM, rpc framework GeeRPC etc) 7天用Go动手写/从零实现系列
文件路径 :Web-Gee/gee/router.go
func newRouter() *router {
return &router{handlers: make(map[string]HandlerFunc)}
}
func (r *router) addRoute(method string, pattern string, handler HandlerFunc) {
log.Printf("Route %4s - %s", method, pattern)
key := method + "-" + pattern
r.handlers[key] = handler
}
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)
}
}
文件路径 :Web-Gee/gee/context.go
type Context struct {
// 待封装的数据对象
Writer http.ResponseWriter
Req *http.Request
// 请求的详细信息
Path string
Method string
// 响应的详细信息
StatusCode int
}
func newContext(w http.ResponseWriter, req *http.Request) *Context {
return &Context{
Writer: w,
Req: req,
Path: req.URL.Path,
Method: req.Method,
}
}
(1)返回 r.Form(解析好的表单数据,包括URL字段的query参数和POST或PUT的表单数据) 中以key为键的[]string字符串切片的第一个值。
func (c *Context) PostForm(key string) string {
return c.Req.FormValue(key)
}
(2)URL.Query() :解析 RawQuery 字段,返回对应的 Values 类型键值对。再根据键值 key 返回对应的值。
func (c *Context) Query(key string) string {
return c.Req.URL.Query().Get(key)
}
(3)显示调用 WriteHeader ,发送 http 回复的头域和状态码。
func (c *Context) Status(code int) {
c.StatusCode = code
c.Writer.WriteHeader(code)
}
(4)Header()方法: 返回一个Header类型值,该值会被WriteHeader方法发送(注意:在调用WriteHeader或Write方法后再改变该对象是没有意义的)。
Set(key, value string)方法:向Header对象添加键值对,如键已存在则会用只有新值一个元素的切片取代旧值切片。
func (c *Context) SetHeader(key string, value string) {
c.Writer.Header().Set(key, value)
}
(5) Write()方法:向连接中写入一部分http的回复数据。如果Header中没有"Content-Type"键,本方法会使用包函数DetectContentType检查数据的前512字节,将返回值作为该键的值(调用 SetHeader 方法)。如果被调用时还未调用WriteHeader,本方法会先调用WriteHeader(http.StatusOK)(调用 Status 方法)
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)))
}
(1)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(), 500)
}
}
(2)HTML类型
func (c *Context) HTML(code int, html string) {
c.SetHeader("Content-Type", "text/html")
c.Status(code)
c.Writer.Write([]byte(html))
}
(3)其它类型数据
func (c *Context) Data(code int, data []byte) {
c.Status(code)
c.Writer.Write(data)
}
文件位置:Web-Gee/main.go
r.GET("/", func(c *gee.Context) {
c.HTML(http.StatusOK, "Hello Gee
")
})
r.POST("/login", func(c *gee.Context) {
c.JSON(http.StatusOK, gee.H{
"username": c.PostForm("username"),
"password": c.PostForm("password"),
})
})
r.GET("/hello", func(c *gee.Context) {
c.String(http.StatusOK, "hello %s, you're at %s\n", c.Query("name"), c.Path)
})
在终端使用 curl命令 进行路由测试