【7days-golang/gee-web/day02】设计Context-学习笔记

主要内容:Gee 框架如何设计和使用 Context 结构体来简化 Web 服务中的常见任务,尤其是响应构造(如 HTML、JSON 等),并通过封装 http.Request 和 http.ResponseWriter 对象提供更高效、简洁的接口。

之前的工作

  • 构建一个基本的框架来接收请求并提供路由功能。
    • 定义了一个结构体 gee.Engine,负责保存所有的路由和处理函数。每一个路由都与一个 HTTP 方法(例如 GET、POST)相关联。
  • 让开发者能够注册不同路径和方法的路由,并关联到处理函数。
    • 负责保存所有的路由和处理函数。每一个路由都与一个 HTTP 方法(例如 GET、POST)相关联。

代码编写

在gee包下新建context.go

创建 Context 结构体

目的:在 Context 中保存请求和响应对象,以及一些帮助方法来操作请求参数和构建响应。从而简化对常见操作的处理。

package geeimport "net/http"type Context struct {// 请求和响应的相关信息Writer http.ResponseWriterReq    *http.Request// 帮助快速获取当前请求的路径和方法。Path   stringMethod stringStatusCode int
}// 工厂函数,负责创建新的 Context 实例,并填充请求相关信息。
func newContext(w http.ResponseWriter, req *http.Request) *Context {return &Context{Writer: w,Req:    req,Path:   req.URL.Path,Method: req.Method,}
}

封装请求参数

目的:我们需要在 Context 中提供方法(在 Context 中添加 Query 和 PostForm 方法)来访问请求的查询参数和表单数据。这样,开发者无需直接操作 http.Request 对象,而是通过 Context 提供的方法来获取数据。简化访问查询参数和表单数据的过程。

func (c *Context) Query(key string) string {return c.Req.URL.Query().Get(key)
}func (c *Context) PostForm(key string) string {return c.Req.FormValue(key)
}

简化响应构建

Web 框架的核心任务之一是构建 HTTP 响应。我们需要提供简洁的方法来发送不同类型的响应,如字符串、JSON 和 HTML。(在 Context 中封装一些方法,例如 String、JSON 和 HTML,来快速生成响应。)

func (c *Context) Status(code int) {c.StatusCode = codec.Writer.WriteHeader(code)
}func (c *Context) SetHeader(key string, value string) {c.Writer.Header().Set(key, value)
}func (c *Context) String(code int, format string, values ...interface{}) { // interface{} 是 Go 中的空接口,它可以接收任何类型的数据(与 Python 或 Java 中的 Object 类似)。然后,方法内部可以通过 fmt.Sprintf 来格式化这些参数。// c.Writer.Header().Set("Content-Type", "text/plain")c.SetHeader("Content-Type", "text/plain")c.Status(code)c.Writer.Write([]byte(fmt.Sprintf(format, values...))) // values... 是将可变参数展开发送给 fmt.Sprintf,它会根据 format 字符串的格式符(如 %s、%d)将参数插入到字符串中。
}func (c *Context) JSON(code int, obj interface{}) { // 通过使用空接口,JSON 方法可以处理任何类型的数据(如结构体、数组、切片、map 等),并将其序列化为 JSON 格式。c.SetHeader("Content-Type", "application/json")c.Status(code)encoder := json.NewEncoder(c.Writer) // 创建了一个新的 将 Go 对象转换为 JSON 的编码器(json.Encoder),它将会把 Go 对象编码为 JSON 格式,并写入到 c.Writer(相当于输出到HTTP响应)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))
}

补充:类型别名

type H map[string]interface{}

map[string]interface{} 是一个键值对类型的映射,键为 string 类型,值为 interface{} 类型。
interface{} 是 Go 中的 空接口,意味着这个 map 可以存储任何类型的值。简单来说,H 就是一个可以存储任意数据类型的字典。
用例:

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

这行代码中,gee.H{} 创建了一个类型为 gee.H 的字典(实际上是 map[string]interface{}),它包含了两个键值对。

运行与测试

总结

Context 设计的必要性

Web服务通常基于两个重要对象:http.Request 和 http.ResponseWriter。但是,这两个对象提供的接口粒度较细,并且对于常见的 Web 服务响应(如 HTML、JSON)来说,需要多次重复配置,容易出错。
比如,创建 JSON 响应时需要手动设置 HTTP 头信息、状态码等。如果没有封装这些常见操作,开发者每次都需要写大量重复的代码。因此,Context 提供了一个简化的接口,封装了这些常用操作,使得开发者只需要关注业务逻辑,不需要处理底层的 HTTP 细节。
框架将复杂的 HTTP 请求和响应操作封装在 Context 中,使得开发者只需要关注业务逻辑,提升开发效率。

语法

接收者(Receiver)是方法定义中的第一个参数,它指定了该方法是作用于哪个类型的实例上的。
在 Go 中,接收者可以是值接收者(Context)或指针接收者(*Context),指针接收者可以修改实例的字段。
c 是 Context 类型的接收者,意味着 JSON 方法是作用于 Context 类型的实例上的,而 c 让你能够在方法中访问和操作 Context 实例。
1. func (c *Context) 表示该方法使用一个指向 Context 类型的指针作为方法的接收者。使用指针作为方法的接收者可以避免结构体实例的拷贝,同时允许方法修改原始结构体的内容。如果将 c 定义为非指针类型(即 Context),那么方法会作用于该结构体的副本,而不是原始结构体。
- 在 Python 和 Java 中,方法通常是类的成员方法,使用 self(Python)或 this(Java)来指代实例。
- 在 Go 中,你可以通过结构体类型实例后面加上指针(如 *Context)来让方法对实例进行修改。
2. 在 Go 中,函数定义通常包括:
- 接收者(Receiver):它与类的方法不同,是关联到一个特定类型上的。Go 没有类的概念,所有的方法都是通过类型(如结构体)来定义的。
- 参数列表(Parameters):定义函数的输入,类似 Python 或 Java 中的参数。
- 返回值(Return Values):定义函数返回的值,可以是多个。
3. 总结:在 Go 中,函数签名包括了一个“接收者”部分,这部分在 Python 和 Java 中通常不需要显式地声明。接收者是一个与类型(如结构体)相关联的特殊参数,它类似于 Python 的 self 或 Java 的 this。你可以通过 *Context 指针接收者来允许方法修改 Context 类型的实例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/23467.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kotlin 知识点 七 泛型的高级特性

对泛型进行实化 泛型实化这个功能对于绝大多数Java 程序员来讲是非常陌生的,因为Java 中完全没有这个概 念。而如果我们想要深刻地理解泛型实化,就要先解释一下Java 的泛型擦除机制才行。 在JDK 1.5之前,Java 是没有泛型功能的,…

Day 49 卡玛笔记

这是基于代码随想录的每日打卡 1143. 最长公共子序列 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变…

重新求职刷题DAY18

1.513. 找树左下角的值 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 输入: root [2,1,3] 输出: 1思路: 这…

因子数个数之和

BDAA实验室的保研机试一道题,有时间限制。 1. 求每个数的因子数再求和:超时 2. 思想转换:统计每个数在 1 到 N 中作为因子出现的次数,从而避免对每个数进行因子分解,将时间复杂度优化到O(N)。( 没想到 :( …

『obsidian』obsidian接入DeepSeek模型的完整说明

一、插件概览 🏆Copilot For Obsidian 开发者:loganc yang | 第 5 届 Ob 宝石奖 LLM 类冠军 核心功能:内置多模态大语言模型,支持自定义模型扩展,实现笔记智能交互预置模型:Claude、GPT-4、Gemini 系列特…

基于YOLO11深度学习的苹果叶片病害检测识别系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

基于 DeepSeek LLM 本地知识库搭建开源方案(AnythingLLM、Cherry、Ragflow、Dify)认知

写在前面 博文内容涉及 基于 Deepseek LLM 的本地知识库搭建使用 ollama 部署 Deepseek-R1 LLM知识库能力通过 Ragflow、Dify 、AnythingLLM、Cherry 提供理解不足小伙伴帮忙指正 😃,生活加油 我站在人潮中央,思考这日日重复的生活。我突然想&#xff0c…

Redis分布式锁故障处理:当Redis不可用时的应对策略

Redis分布式锁故障处理:当Redis不可用时的应对策略 在分布式系统中,Redis因其高性能和丰富的特性常被用于实现分布式锁。但当加锁过程中Redis服务不可用时,系统将面临严重挑战。本文将深入探讨这一问题,并提供多维度解决方案。 目…

番外·卓伊凡参加 [2025年2月HDD·鸿蒙赋能交流会·成都站] 线下活动的心得体会-优雅草卓伊凡

番外卓伊凡参加 [2025年2月HDD鸿蒙赋能交流会成都站] 线下活动的心得体会-优雅草卓伊凡 背景 2025 年 2 月 22 日,HDD・鸿蒙赋能交流会将在北京、长沙、成都、南京、雄安同步开展。此次交流会由 HDG 组织者牵头,携手 HUAWEI DEVELOPER EXPERTS&#xf…

vue-fastapi-admin 部署心得

vue-fastapi-admin 部署心得 这两天需要搭建一个后台管理系统,找来找去 vue-fastapi-admin 这个开源后台管理框架刚好和我的技术栈所契合。于是就浅浅的研究了一下。 主要是记录如何基于原项目提供的Dockerfile进行调整,那项目文件放在容器外部&#xf…

永洪科技旗下BI产品,成功入选“金融信创优秀解决方案“

3月28日至29日,金融信创生态实验室在京举办金融信创解决方案研讨会,发布第三期金融信创优秀解决方案、实验室推荐解决方案,启动解决方案的分享活动。 永洪科技凭借旗下的敏捷BI数据分析平台,成功入选“金融信创优秀解决方案&…

Android之APP更新(通过接口更新)

文章目录 前言一、效果图二、实现步骤1.AndroidManifest权限申请2.activity实现3.有版本更新弹框UpdateappUtilDialog4.下载弹框DownloadAppUtils5.弹框背景图 总结 前言 对于做Android的朋友来说,APP更新功能再常见不过了,因为平台更新审核时间较长&am…

PHP课程预约小程序源码

📱 课程预约小程序:为您专属定制的便捷预约新体验 在这个快节奏的时代,我们深知每一位瑜伽爱好者、普拉提追随者以及培训机构管理者对高效、便捷服务的迫切需求。因此,我们匠心独运,推出了一款基于PHPUniApp框架开发的…

WebXR教学 02 配置开发环境

默认操作系统为Windows 1.VS Code VS Code 是一款轻量级、功能强大的代码编辑器,适用于多种编程语言。 下载 步骤 1:访问 VS Code 官方网站 打开浏览器(如 Chrome、Edge 等)。 在地址栏输入以下网址: https://code.v…

unity学习51:所有UI的父物体:canvas画布

目录 1 下载资源 1.1 在window / Asset store下下载一套免费的UI资源 1.2 下载,导入import 1.3 导入后在 project / Asset下面可以看到 2 画布canvas,UI的父物体 2.1 创建canvas 2.1.1 画布的下面是 event system是UI相关的事件系统 2.2 canvas…

JavaWeb开发入门:从前端到后端的完整流程解析

一、JavaWeb简介 1、C/S 客户端/服务器结构 2、B/S(Browser/Server,浏览器/服务器)结构 二、开发环境搭建 1. 安装Tomcat--一个小型的web容器。 2. 在eclipse中配置tomcat创建项目 三、JavaWeb开发流程 1. 前端页面设计 2. 后端逻辑…

Linux 常见命令全解析

一、文件操作命令 1. ls ls是列出目录内容的命令。简单输入ls,会展示当前目录下的文件和目录列表。想要获取更详细的信息,比如文件权限、所有者、大小、修改时间等,使用ls -l。若要显示所有文件,包括以点(.&#xff…

unordered_set和unordered_map的使用

Hello,今天我来为大家介绍一下前几年才刚刚新出的两个容器——unordered_map和unordered_set,这两个容器属于是map系列和set系列中的一种,和map/set不同的是它们的底层,map/set的底层是红黑树,而unordered_map/unorder…

【每日八股】计算机网络篇(一):概述

OSI 的 7 层网络模型? OSI(Open Systems Interconnection,开放互联系统)是由国际标准化组织(ISO)提出的一种网络通信模型。 自上而下,OSI 可以被分为七层,分别是:应用层…

DeepSeek 提示词:高效的提示词设计

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…