学习Go语言Web框架Gee总结--上下文Context(二)

学习Go语言Web框架Gee总结--上下文Context

学习网站来源:Gee

项目目录结构:

context/go.mod

go 复制代码
module example

go 1.21.5

require gee v0.0.0
replace gee => ./gee

context/main.go

go 复制代码
package main

import (
	"gee"
	"net/http"
)

func main() {
	r := gee.New()
	//http.StatusOK为常量200
		c.HTML(http.StatusOK, "<h1>Hello Gee</h1>")
	})
	r.GET("/hello", func(c *gee.Context) {
		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")
}

Handler的参数变成成了gee.Context,提供了查询Query/PostForm参数的功能

/hello?firstname=Jane&lastname=Doe这样一个路由, firstname, lastname即是Querystring parameters, 要获取他们就需要使用Query相关函数.

go 复制代码
c.Query("firstname") // Jane
c.Query("lastname") // Doe

对于POST, PUT等这些能够传递参数Body的请求, 要获取其参数, 需要使用PostForm

go 复制代码
{
    "username":wang,
    "password":123
}
go 复制代码
username:= c.PostForm("username")
password:= c.PostForm("password")

效果如下:

对于post请求

context/gee/context.go

go 复制代码
package gee

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type H map[string]interface{}

//自定义的Context结构体是一个用于在处理 HTTP 请求时封装请求上下文信息的工具,它简化了处理请求和返回响应的过程,提供了更加友好和便利的接口
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,
	}
}

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)
}
//用于返回一个字符串格式的响应,设置响应头的 Content-Type 为 text/plain,并将格式化后的字符串写入到响应体中
func (c *Context) String(code int, format string, values ...interface{}) {
	c.SetHeader("Context-Type", "text/plain")
	c.Status(code)
	c.Writer.Write([]byte(fmt.Sprintf(format, values...)))
}
//使用json.NewEncoder将对象编码为JSON格式并写入到响应体中,如果在编码过程中出现错误,会返回 500 状态码
func (c *Context) JSON(code int, obj interface{}) {
	c.SetHeader("Context-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)
}
//用于返回 HTML 内容,它接受一个状态码和一个 HTML 字符串作为参数
func (c *Context) HTML(code int, html string) {
	c.SetHeader("Content-Type", "text/html")
	c.Status(code)
	c.Writer.Write([]byte(html))
}

关于HTTP中的Context-Type

常见的媒体格式类型如下:

  • text/html : HTML格式
  • text/plain :纯文本格式
  • text/xml : XML格式
  • image/gif :gif图片格式
  • image/jpeg :jpg图片格式
  • image/png:png图片格式

以application开头的媒体格式类型:

  • application/xhtml+xml :XHTML格式
  • application/xml: XML数据格式
  • application/atom+xml :Atom XML聚合格式
  • application/json: JSON数据格式
  • application/pdf:pdf格式
  • application/msword : Word文档格式
  • application/octet-stream : 二进制流数据(如常见的文件下载)
  • application/x-www-form-urlencoded : 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

另外一种常见的媒体格式是上传文件之时使用的:

multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式

context/gee/router.go

将和路由相关的方法和结构单独提取了出来,放到了一个新的文件中router.go,方便我们下一次对 router 的功能进行增强,例如提供动态路由的支持

go 复制代码
package gee

import (
	"log"
	"net/http"
)

type router struct {
	handlers map[string]HandlerFunc
}

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)
	}
}

context/gee/gee.go

框架入口

go 复制代码
package gee

import "net/http"

type HandlerFunc func(*Context)

type Engine struct {
	router *router
}

func New() *Engine {
	return &Engine{router: newRouter()}
}

func (engine *Engine) addRoute(method string, pattern string, handler HandlerFunc) {
	engine.router.addRoute(method, pattern, handler)
}

func (engine *Engine) GET(pattern string, handler HandlerFunc) {
	engine.addRoute("GET", pattern, handler)
}

func (engine *Engine) POST(pattern string, handler HandlerFunc) {
	engine.addRoute("POST", pattern, handler)
}

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

func (engine *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	c := newContext(w, r)
	engine.router.handle(c)
}
相关推荐
Estar.Lee3 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
Red Red4 小时前
网安基础知识|IDS入侵检测系统|IPS入侵防御系统|堡垒机|VPN|EDR|CC防御|云安全-VDC/VPC|安全服务
网络·笔记·学习·安全·web安全
2401_857610034 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_5 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞5 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货5 小时前
Rust 的简介
开发语言·后端·rust
Natural_yz5 小时前
大数据学习17之Spark-Core
大数据·学习·spark
qq_172805595 小时前
RUST学习教程-安装教程
开发语言·学习·rust·安装
monkey_meng5 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
一只小小汤圆6 小时前
opencascade源码学习之BRepOffsetAPI包 -BRepOffsetAPI_DraftAngle
c++·学习·opencascade