基于gin框架的文件上传(逐行解析)

            基于gin框架的文件上传(逐行解析)

记录一下使用gin框架完成一个文件上传的功能,一下是实现该功能的代码,适合小白,代码都有逐行解释!

app.go:

package routerimport ("chat/service""github.com/gin-gonic/gin"
)func Router() *gin.Engine {r := gin.Default()//上传文件,使用post请求r.POST("/attach/upload", service.Upload)return r
}

attach.go:

package serviceimport ("chat/utils""fmt""github.com/gin-gonic/gin""io""math/rand""net/http""os""strings""time"
)func Upload(c *gin.Context) {UploadLocal(c)
}// 上传文件到本地
func UploadLocal(c *gin.Context) {w := c.Writer //获取响应的gin上下文写入器req := c.Request//获取当前请求对象//从请求中通过FormFile方方法获取指定名称("file")的文件//srcFile为获取到的源文件//head为文件的头部信息//err为可能出现的错误srcFile, head, err := req.FormFile("file") if err != nil {//使用utils.RespFail()函数响应写入失败信息和错误内容utils.RespFail(w, err.Error())}
//定义默认的文件后缀为".png"suffix := ".png"//从head中获取文件信息head有以下常用变量//head.Header 文件的头部信息,包含一些与文件相关的元数据,比如文件的类型、大小//head.Size 文件的大小//head.Filename 文件的名字ofilName := head.Filename //定义一个字符串切片tem,使用strings。Split()将文件名ofilName按照(.)进行分割再装入这个切片当中,tem := strings.Split(ofilName, ".")//如果分割后的结果长度大于1,表示有后缀if len(tem) > 1 {// 将后缀更新为分割后的最后一部分(该切片的最后一个元素)suffix = "." + tem[len(tem)-1]}// 根据当前时间的 Unix 时间戳、随机生成的 32 位整数和后缀生成文件名fileName := fmt.Sprintf("%d%04d%s", time.Now().Unix(), rand.Int31(), suffix)//使用os.Create()在指定路径("./files/"+fileName)创建新的文件dstFile, err := os.Create("./files/" + fileName)if err != nil {//使用utils.RespFail()函数响应写入失败信息和错误内容utils.RespFail(w, err.Error())}// 使用 io.Copy 方法将源文件的内容拷贝到目标文件中// err 为可能出现的拷贝过程中的错误_, err = io.Copy(dstFile, srcFile)if err != nil {//使用utils.RespFail()函数响应写入失败信息和错误内容utils.RespFail(w, err.Error())}//构建文件的完整的URLurl := "./files/" + fileName// 使用 utils.RespOK 函数向响应写入成功信息、文件的 URL 以及成功消息utils.RespOK(w, url, "发送成功")
}

resp.go:主要用处理请求响应的各种状态

package utilsimport (// 导入相关包"encoding/json""fmt""net/http"
)type H struct {// 定义结构体 H,包含代码、消息、数据、行数和总数等字段Code  intMsg   stringData  interface{}Rows  interface{}Total interface{}
}// Resp 函数,用于响应数据
func Resp(w http.ResponseWriter, code int, data interface{}, msg string) {// 设置响应头的内容类型为 JSONw.Header().Set("Content-Type", "application/json")// 设置响应状态码为 200(OK)w.WriteHeader(http.StatusOK)h := H{// 初始化结构体 H 的字段Code: code,Data: data,Msg:  msg,}// 对结构体 H 进行 JSON 序列化操作ret, err := json.Marshal(h)if err!= nil {// 处理序列化错误fmt.Println(err)}w.Write(ret)
}// RespList 函数,用于响应列表数据
func RespList(w http.ResponseWriter, code int, data interface{}, total interface{}) {w.Header().Set("Content-Type", "application/json")w.WriteHeader(http.StatusOK)h := H{// 初始化结构体 H 的字段Code:  code,Rows:  data,Total: total,}ret, err := json.Marshal(h)if err!= nil {// 处理序列化错误fmt.Println(err)}w.Write(ret)
}// RespFail 函数,用于响应失败信息
func RespFail(w http.ResponseWriter, msg string) {// 调用 Resp 函数,设置代码为-1,表示失败Resp(w, -1, nil, msg)
}// RespOK 函数,用于响应成功信息
func RespOK(w http.ResponseWriter, data interface{}, msg string) {// 调用 Resp 函数,设置代码为 0,表示成功Resp(w, 0, data, msg)
}// RespOKList 函数,用于响应成功的列表信息
func RespOKList(w http.ResponseWriter, data interface{}, total int) {// 调用 RespList 函数,设置代码为 0,表示成功RespList(w, 0, data, total)
}

main.go:

package mainimport "chat/router"func main() {r := router.Router()r.Run(":8081")
}

写完了:测试一下

使用postman提交一个文件参数

在这里插入图片描述

查看是否上传成功

在这里插入图片描述

可以看到文件上传成功了!

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

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

相关文章

网络工程师练习题

网络工程师练习题 网桥怎样知道网络端口连接了那些网站?如果从端口收到一个数据帧,则将其源地址记入该端口的数据库当网桥连接的局域网出现环路时怎么办?运行生成树协议阻塞一部分端口。使用IEEE 802.1q协议,最多可以配置4094个VLAN。VLAN中继协议(VTP)有不同的工作模式,…

C++异常详解

文章目录 前言一、回顾C语言二、异常的概念三、异常的使用1.异常的抛出和捕获2.异常的重新捕获 三.异常安全与异常规范1.异常安全2.异常规范 四.自定义异常体系五.C标准库的异常体系六.异常优缺点练习题总结 前言 在本篇文章中,我们将会详细介绍一下有关C异常的讲解…

微服务架构:注册中心 Eureka、ZooKeeper、Consul、Nacos的选型对比详解

微服务架构(Microservices Architecture)是一种基于服务拆分的分布式架构模式,旨在将复杂的单体应用程序拆分为一组更小、更独立的服务单元。这些服务单元可以独立开发、测试、部署,并使用不同的技术栈和编程语言。它们通过轻量级…

[华为OD] C卷 dfs 特殊加密算法 100

题目: 有一种特殊的加密算法,明文为一段数字串,经过密码本查找转换,生成另一段密文数字串。 规则如下 1•明文为一段数字串由0-9组成 2.密码本为数字0-9组成的二维数组 3•需要按明文串的数字顺序在密码本里找到同样的数字串…

PUBG非升级实用枪皮-部分盘点

藏匿处的黑货箱武器需要耗费高额成本才能升级 对于像我这样的日常休闲玩家来说是一笔不小的(巨大的!)负担 其实有许多普通非升级枪皮也是不错的选择 今天就来盘点一下我自己日常在用的普通皮 来看看你是不是也在用一样的 (仅是盘点…

【OceanBase诊断调优】—— 租户资源统计项及其查询方法

本文主要介绍 OceanBase 数据库中租户资源统计项及其查询方法。 适用版本 OceanBase 数据库 V4.1.x、V4.2.x 版本。 CPU 资源统计项 逻辑 CPU 使用率(线程处理请求的时间占比)。 通过虚拟表 __all_virtual_sysstat 在 SYS 系统租户下,查看…

09.zabbix自定义模块并使用

zabbix自定义模块并使用 根据tcp的11中状态获取值,进行批量配置监控项 [rootyunlong66 ~]# cat /etc/zabbix/zabbix_agentd.d/tcp.conf UserParameterESTABLISHED,netstat -antp |grep -c ESTABLISHED UserParameterSYN_SENT,netstat -antp |grep -c SYN_SENT Use…

Obsidian/Typora设置图床

在obsidian中默认图片是保存在本地的,但是在要导出文档上传到网上时,由于图片保存在本地,会出现无法加载图片的问题。 这里引用的一段话: 这里使用picgo-core和gitee实现图床功能, 参考1: Ubuntu下PicGO配…

Github学习

1.Git与Github 区别: Git是一个分布式版本控制系统,简单的说就是一个软件,用于记录一个或若干个文件内容变化,以便将来查阅特点版本修订情况的软件。 Github是一个为用户提高Git服务的网站,简单说就是一个可以放代码的地方。Gi…

C语言 | Leetcode C语言题解之第85题最大矩形

题目&#xff1a; 题解&#xff1a; int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize) {int m matrixSize;if (m 0) {return 0;}int n matrixColSize[0];int left[m][n];memset(left, 0, sizeof(left));for (int i 0; i < m; i) {for (int j …

SeetaFace6人脸活体检测C++代码实现Demo

SeetaFace6包含人脸识别的基本能力&#xff1a;人脸检测、关键点定位、人脸识别&#xff0c;同时增加了活体检测、质量评估、年龄性别估计&#xff0c;并且顺应实际应用需求&#xff0c;开放口罩检测以及口罩佩戴场景下的人脸识别模型。 官网地址&#xff1a;https://github.co…

【补充】图神经网络前传——DeepWalk

论文阅读 论文&#xff1a;https://arxiv.org/pdf/1403.6652 参考&#xff1a;【论文逐句精读】DeepWalk&#xff0c;随机游走实现图向量嵌入&#xff0c;自然语言处理与图的首次融合_随机游走图嵌入-CSDN博客 abstract DeepWalk是干什么的&#xff1a;在一个网络中学习顶点…

【Mac】Ghost Buster Pro(苹果电脑内存清理专家) v3.2.5安装教程

软件介绍 Ghost Buster pro是一款针对Mac系统的电脑清理和优化工具&#xff0c;可以帮助用户清理系统垃圾、修复注册表错误、卸载不需要的软件、管理启动项等&#xff0c;从而提高系统性能和稳定性。 安装教程 1.打开镜像包&#xff0c;拖动「Ghost Buster Pro」到应用程序中…

【Linux网络】Https【下】{CA认证/证书的签发与认证/安全性/总结}

文章目录 1.引入证书【为方案五铺垫】1.1再谈https1.2SSL/TLS1.3CA机构1.4理解数字签名1.4继续铺垫1.5方案五服务端申请证书回顾一二三回顾方案四方案五过程寻找方案五的漏洞客⼾端对证书进⾏认证 2.查看证书2.1查看浏览器的受信任证书发布机构2.2中间⼈有没有可能篡改该证书2.…

差分约束 C++ 算法例题

差分约束 差分约束 是一种特殊的 n 元一次不等式组&#xff0c;m 个约束条件&#xff0c;可以组成形如下的格式&#xff1a; { x 1 − x 1 ′ ≤ y 1 x 2 − x 2 ′ ≤ y 2 ⋯ x m − x m ′ ≤ y m \begin{cases} x_1-x_1^{} \le y_1 \\ x_2-x_2^{} \le y_2 \\ \cdots \\ x_…

SpringBoot集成jxls2实现复杂(多表格)excel导出

核心依赖 需求 导出多个表格&#xff0c;包含图片&#xff0c;类似商品标签 1.配置模板 创建一个xlsx的模板文件&#xff0c;配置如下 该模板进行遍历了两次&#xff0c;因为我想要导出的数据分为两列展示&#xff0c;左右布局&#xff0c;一个循环实现不了&#xff0c;所以采…

百面算法工程师 | 正则优化函数——BN、LN、Dropout

本文给大家带来的百面算法工程师是正则优化函数&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们将总结一些BN、LN、Dropout的相关知识&#xff0c;并提供参考的回答及其理论基础&#xff0c;以…

C++ | Leetcode C++题解之第85题最大矩形

题目&#xff1a; 题解&#xff1a; class Solution { public:int maximalRectangle(vector<vector<char>>& matrix) {int m matrix.size();if (m 0) {return 0;}int n matrix[0].size();vector<vector<int>> left(m, vector<int>(n, 0)…

【HCIP学习】BGP对等体组、聚合、路由反射器、联盟、团体属性

一、大规模BGP网络所遇到的问题 BGP对等体众多&#xff0c;配置繁琐&#xff0c;维护管理难度大 BGP路由表庞大&#xff0c;对设备性能提出挑战 IBGP全连接&#xff0c;应用和管理BGP难度增加&#xff0c;邻居数量过多 路由变化频繁&#xff0c;导致路由更新频繁 二、解决大…

使用QT-QSqlQuery::value()遇到的问题

在实现客户端间好友添加功能时&#xff0c;我通过以下函数想实现数据库对好友信息的保存 bool OpeDB::handleAddFriend_repound(const char *pername, const char *name) { // pername 被添加方 name 申请添加方 qDebug() << pername << " " &l…