Gin框架: 通用方法的封装与上传功能的应用

golang——Gin框架及路由介绍 gin框架中采用的路由库是基于httprouter做的支持Restful风格的API,意思是"表面层状态转化",是一个互联网应用程序的API设计理念:URL定位资源。可以创建路由组,为了管理相同的URL。import ("net/http"//将应用切换到“发布模式”以提升性能//创建路由//默认使用了两个中间件Logger(),Recovery()})})//路由组1})})//路由组2})})//监听端口,默认绑定端口8080。 阅读详情

通用方法模块的设计


  • 通用的方法可以定义在一个模块里,以方便调用,无需重复造轮子
  • 一般可以设计一个顶层的 models 包来承载公共方法

models 包

package models

import (
	"crypto/md5"
	"encoding/hex"
	"math/rand"
	"time"
	"fmt"
	"io"
)

// 通用时间模板定义
var goTime = "2006-01-02 15:04:05"
var shortGoTime = "2006-01-02"
var md5Salt = GenerateSalt(16) // 加密时用的盐

// 时间戳转换成日期
func UnixToTime(timestamp int) string {
	t := time.Unix(int64(timestamp), 0)
	return t.Format(goTime)
}

// 日期转换成时间戳
func DateToUnix(str string) int64 {
	t, err := time.ParseInLocation(goTime, str, time.Local)
	if err != nil {
		return 0
	}
	return t.Unix()
}

// 获取时间戳
func GetUnix() int64 {
	return time.Now().Unix()
}

// 获取当前的日期
func GetDate() string {
	return time.Now().Format(goTime)
}

// 获取年月日
func GetDateShort() string {
	return time.Now().Format(shortGoTime)
}

// GenerateSalt 生成一个指定长度的随机盐  
func GenerateSalt(length int) string {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	var seededRand *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))
	b := make([]byte, length)
	for i := range b {
		b[i] = charset[seededRand.Intn(len(charset))]
	}
	return string(b)
}

// MD5Hash 计算并返回给定字符串的 MD5 哈希值
func Md5Hash(text string) string {
	hasher := md5.New()
	hasher.Write([]byte(text + md5Salt))
	md5Bytes := hasher.Sum(nil)
	return hex.EncodeToString(md5Bytes)
}

// 第二种加密方式,和上述结果一致
func Md5Hash2(text string) string {
	md5str := fmt.Sprintf("%x", md5.Sum([]byte(text + md5Salt)))
	return md5str
}

// 第三种加密方法
func Md5Hash3(text string) string {
	hasher := md5.New()
	io.WriteString(hasher, text + md5Salt)
	md5str := fmt.Sprintf("%x", hasher.Sum(nil))
	return md5str
}

// VerifyMD5Hash 验证给定的明文密码是否与存储的哈希值匹配
func VerifyMD5Hash(plainPassword, storedHash string) bool {
	return storedHash == Md5Hash(plainPassword)
}
  • 上述的方法,可以写在程序里,通过models来调用,也可配置全局,在模板里调用

main.go 主程序

package main

import (
	"gin-demo/routers" // gin-demo 是 go mod init 初始化的工程,下同
	"github.com/gin-gonic/gin"
	"html/template"
	"gin-demo/models"
)

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()

	// 自定义模板函数  注意要把这个函数放在加载模板前 全局配置
	r.SetFuncMap(template.FuncMap{
		"UnixToTime": models.UnixToTime,
		"DateToUnix": models.DateToUnix,
		"GetUnix": models.GetUnix,
		"GetDate": models.GetDate,
		"GetDateShort": models.GetDateShort,
	})

	// 加载模板 放在配置路由前面
	r.LoadHTMLGlob("tpls/**/*")

	routers.WebRoutersInit(r)
	routers.ApiRoutersInit(r)
	routers.AdminRoutersInit(r)

	r.Run()
}

web首页控制器

package web

import (
	"gin-demo/models"
	"net/http"
	"github.com/gin-gonic/gin"
)

type WebCtrl struct{}

func (con WebCtrl) Index(c *gin.Context) {
	// 验证加密和验证
	originStr := "dsdssdsdsfdsdsfss" // 原字符
	md5HashStr := models.Md5Hash(originStr) // 加密后的字符串
	checkMd5Result := models.VerifyMD5Hash(originStr, md5HashStr) // 加密后的验证
	c.HTML(http.StatusOK, "web/index.html", gin.H{
		"msg": "我是一个msg",
		"t":   1760025600,
		"d": "2025-10-10 00:00:00",
		"originStr": originStr, // 原字符串
		"md5HashStr": md5HashStr, // md5 加密后的字符串
		"checkMd5Result": checkMd5Result, // 验证是否匹配
		"testMd5_2": models.Md5Hash2(originStr), // 第二种加密结果
		"testMd5_3": models.Md5Hash3(originStr), // 第三种加密结果
	})
}

web首页模板 tpls/web/index.html

{{ define "web/index.html" }}

  <h3>web index 页面</h3>
  {{.msg}}

  <h3> UnixToTime 时间处理</h3>
  {{ UnixToTime .t }} <br />
  {{ .t | UnixToTime }}
  <h3> DateToUnix 时间处理</h3>
  {{ .d | DateToUnix }} <br />
  {{ DateToUnix .d }}
  <h3> GetUnix 时间处理</h3>
  {{ GetUnix }} <br />
  <h3> GetDate 时间处理</h3>
  {{ GetDate }}
  <h3> GetUnix 时间处理</h3>
  {{ GetDateShort }}
  <h3> md5 原字符串 </h3>
  {{ .originStr }}
  <h3> md5 加密后的hash </h3>
  {{ .md5HashStr }}
  <h3> md5 验证是否相同 </h3>
  {{ .checkMd5Result }}
  <h3> md5 第二种md5加密方式得到的字符串 </h3>
  {{ .testMd5_2 }}
  <h3> md5 第三种md5加密方式得到的字符串 </h3>
  {{ .testMd5_3 }}

{{ end }}

效果图

  • 如果我们的应用非常简单的话,我们可以在 Controller 里面处理常见的业务逻辑
  • 但是如果我们有一个功能想在多个控制器、或者多个模板里面复用的话
  • 那么我们就可以把公共的功能单独抽取出来作为一个模块(Models)
  • Model 是逐步抽象的过程,一般我们会在 Model
  • 里面封装一些公共的方法让不同 Controller 使用
  • 也可以在 Model 中实现和数据库打交道
  • 以上是这些应用场景,和其他项目设计都是一致的思路

上传功能


这里上传分多种场景:上传单张图片,上传多张图片
在上传多张图片中又分为,同一文件字段和不同文件字段的处理

1 ) 设计路由

package routers

import (
	"gin-demo/controllers/admin"
	"gin-demo/middlewares" // 引入
	"github.com/gin-gonic/gin"
)

func AdminRoutersInit(r *gin.Engine) {
	adminRouters := r.Group("/admin", middlewares.InitMiddleware) // 注意这里
	{
		adminRouters.GET("/", admin.IndexCtrl{}.Index)
		adminRouters.GET("/user", admin.UserCtrl{}.Index)
		adminRouters.GET("/user/success", admin.UserCtrl{}.Success)
		adminRouters.GET("/user/error", admin.UserCtrl{}.Error)
		adminRouters.GET("/user/upload", admin.UserCtrl{}.Upload) // 这是单个上传页面
		adminRouters.GET("/user/uploads", admin.UserCtrl{}.Uploads) // 这个是多文件上传页面,在这个页面中有两个上传入口
		adminRouters.POST("/user/doUpload", admin.UserCtrl{}.DoUpload) // 处理单个上传
		adminRouters.POST("/user/doUploads", admin.UserCtrl{}.DoUploads) // 处理多个上传(同一字段)
		adminRouters.POST("/user/doUploads2", admin.UserCtrl{}.DoUploads2) // 处理多个上传(不同字段)
	}
}

2 ) main 文件中对上传路径和模板的处理

package main

import (
	"gin-demo/routers" // gin-demo 是 go mod init 初始化的工程,下同
	"github.com/gin-gonic/gin"
	"html/template"
	"gin-demo/models"
)

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()

	// 自定义模板函数  注意要把这个函数放在加载模板前 全局配置
	r.SetFuncMap(template.FuncMap{
		"UnixToTime": models.UnixToTime,
		"DateToUnix": models.DateToUnix,
		"GetUnix": models.GetUnix,
		"GetDate": models.GetDate,
		"GetDateShort": models.GetDateShort,
	})

	// 加载模板 放在配置路由前面
	r.LoadHTMLGlob("tpls/**/**/*")
	// 配置静态web目录   第一个参数表示路由, 第二个参数表示映射的目录
	r.Static("/static", "./static")

	routers.WebRoutersInit(r)
	routers.ApiRoutersInit(r)
	routers.AdminRoutersInit(r)

	r.Run()
}

注意了,这个之前的项目中,首页模板修改成 tpls/web/home/index.html 就不会有问题了 (这个可忽略,因为不涉及)

主要是这两个

// 加载模板 放在配置路由前面
r.LoadHTMLGlob("tpls/**/**/*")
// 配置静态web目录   第一个参数表示路由, 第二个参数表示映射的目录
r.Static("/static", "./static")

3 )HTML 模板文件处理

3.1 单个上传

{{ define "admin/user/upload.html" }}

    <h2>演示单一文件上传</h2>

    <form action="/admin/user/doUpload" method="post" enctype="multipart/form-data">
        
        用户名:<input type="text" name="username" placeholder="用户名" />
        <br>
        <br>
        头 像<input type="file" name="face" />
        <br>    <br>

        <input type="submit" value="提交">
    </form>

{{ end }}

3.2 多个上传

{{ define "admin/user/uploads.html" }}

    <h2>演示多文件上传:相同文件字段</h2>

      <form action="/admin/user/doUploads" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="username" placeholder="用户名" />
        <br>
        <br>
        头 像1:<input type="file" name="face[]" />
        <br> <br>
        头 像2:<input type="file" name="face[]" />
        <br> <br>
        头 像3:<input type="file" name="face[]" />
        <br> <br>
        <input type="submit" value="提交">
    </form>
    <br />
    <hr />
    <br />
    <h2>演示多文件上传:不同的文件字段</h2>
      <form action="/admin/user/doUploads2" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="username" placeholder="用户名" />
        <br>
        <br>
        头 像1:<input type="file" name="face1" />
        <br> <br>
        头 像2:<input type="file" name="face2" />
        <br> <br>
        <input type="submit" value="提交">
    </form>

{{ end }}

4 ) 上传控制器

package admin

import (
	"gin-demo/models"
	"mime/multipart"
	"net/http"
	"os"
	"path"
	"strconv"
	"time"
	"math/rand"
	"github.com/gin-gonic/gin"
)

type UserCtrl struct {
	BaseCtrl
}

// 获取 单一上传 页面
func (con UserCtrl) Upload(c *gin.Context) {
	c.HTML(http.StatusOK, "admin/user/upload.html", gin.H{})
}

// 获取 多上传 页面
func (con UserCtrl) Uploads(c *gin.Context) {
	c.HTML(http.StatusOK, "admin/user/uploads.html", gin.H{})
}

// 允许的后缀判断
func checkAllowedExt(extName string, c *gin.Context) bool {
	allowExtMap := map[string]bool{ ".jpg": true, ".png": true, ".gif": true, ".jpeg": true, }
	if _, ok := allowExtMap[extName]; !ok {
		return false
	}
	return true
}

// 获取文件路径
func saveFile(file *multipart.FileHeader, c *gin.Context) string {
	fileName := file.Filename
	extName := path.Ext(fileName) // 获取后缀
	// 判断文件后缀名是否正确 .jpg .png .gif .jpeg
	if (!checkAllowedExt(extName, c)) {
		c.String(200, "文件类型不合法")
		return ""
	}
	// 处理文件存储路径
	day := models.GetDateShort()
	dir := "./static/upload/" + day
	// 0777用来测试 生产环境应使用 0666 让其不可执行,保证安全性
	if err := os.MkdirAll(dir, 0777); err != nil {
		// 处理错误
		return ""
	}
	source := rand.NewSource(time.Now().UnixNano()) // 初始化随机数种子
	rnd := rand.New(source) // 使用新的随机数源创建一个随机数生成器
	random10DigitNumber := rnd.Intn(9000000000) + 1000000000 // 生成一个10位的随机整数  
	// 没有错误 生成文件名称 144325235235_xxxxxxxxxx.png
	fileUnixName := strconv.FormatInt(models.GetUnix(), 10) + "-" + strconv.Itoa(random10DigitNumber)
	//static/upload/20200623/144325235235.png
	savedDir := path.Join(dir, fileUnixName + extName)
	// 存储
	c.SaveUploadedFile(file, savedDir)
	return savedDir
}

// 处理 单一上传 提交
func (con UserCtrl) DoUpload(c *gin.Context) {
	// 获取表单
	username := c.PostForm("username") // 获取字段
	file, err := c.FormFile("face") // 获取文件
	if err != nil {
		// 处理错误
		c.String(http.StatusOK, "文件错误:%v", err)
		return
	}
	// 保存文件位置
	dst := saveFile(file, c)
	if dst == "" {
		return
	}
	// 响应json
	c.JSON(http.StatusOK, gin.H{
		"success":  true,
		"username": username,
		"dst":      dst,
	})
}

// 处理 多上传 提交:相同字段
func (con UserCtrl) DoUploads(c *gin.Context) {
	// 获取表单
	username := c.PostForm("username")
	form, _ := c.MultipartForm()
	// 处理文件
	files := form.File["face[]"]
	// 没有文件的校验
	if (len(files) == 0) {
		// 做一些处理
		c.String(http.StatusOK, "没上传一张图片!")
		return
	}
	var dsts []string
	// 处理文件
	for _, file := range files {
		// 进入存储流程
		dst := saveFile(file, c)
		if (dst == "") {
			continue
		}
		dsts = append(dsts, dst)
	}
	c.JSON(http.StatusOK, gin.H{
		"success":  true,
		"username": username,
		"dst": dsts,
	})
}

// 处理 多上传 提交:不同字段
func (con UserCtrl) DoUploads2(c *gin.Context) {
	// 表单处理
	username := c.PostForm("username")
	file1, err1 := c.FormFile("face1")
	file2, err2 := c.FormFile("face2")

	// 错误处理:上传文件到指定的目录
	if !(err1 == nil || err2 == nil) {
		c.String(200, "没有上传文件")
		return;
	}
	// 保存文件
	var dsts []string
	// 处理文件
	if file1 != nil {
		dst1 := saveFile(file1, c)
		if (dst1 != "") {
			dsts = append(dsts, dst1)
		}
	}
	if file2 != nil {
		dst2 := saveFile(file2, c)
		if (dst2 != "") {
			dsts = append(dsts, dst2)
		}
	}
	// 响应
	c.JSON(http.StatusOK, gin.H{
		"success":  true,
		"username": username,
		"dst": dsts,
	})
}

5 ) 聊聊注意事项

  • 上传文件注意 html 模板中设置 enctype="multipart/form-data" 这个是关键
  • 上传时,如果有文件服务器,需要上传到文件服务器中,这里只演示本服务器上传基础功能
  • 上传图片时的路径处理,包括按照时间来创建目录和文件
  • 这里仅是一个示例程序,用于学习和交流,可以基于此来改造
Go Gin框架文件上传实战指南与curl操作教程 cURL是一个开源的命令行工具和库,用于发送和接收数据。它支持多种协议,如HTTP、HTTPS、FTP等,广泛用于文件上传下载、接口测试等场景。cURL的选项和参数非常丰富,可以精细地控制传输行为。-X选项用于指定请求的类型(GET、POST、PUT等)。-H选项用于添加请求头。-F选项用于模拟表单数据发送文件。-o选项用于将响应数据输出到文件。-s选项用于静默模式,不显示进度条和错误信息。-T选项用于指定本地文件上传到远程服务器。选项用于附加字符串到-F。 阅读详情

相关推荐

Go Gin MVC框架脚手架

Go Gin MVC框架脚手架,下载下来可直接使用。包括Controllers、Middlewares、Modles、Services、Sessions等, 封装严谨,代码规范。

Go--封装Gin框架(Curd)

Gin封装框架

qq_63530862的博客 1606

GinSkeleton:基于go语言gin框架封装的web项目骨架

这是什么? 1.这是一个基于go语言gin框架的web项目骨架,专注于前后端分离的业务场景,其目的主要在于将web项目主线逻辑梳理清晰,最基础的东西封装完善,开发者更多关注属于自己的的业务即可。 2.本项目骨架封装了以tb_users表为核心的全部功能(主要包括用户相关的接口参数验证器、注册、登录获取token、刷新token、CURD以及token鉴权等),开发者拉取本项目骨架,在此基础上就可以快速开发自己的项目。 3.本项目骨架请使用 master 分支版本即可, 该分支是最新稳定分支 . 4.本项目骨架从V1.4.00开始,要求go语言版本 >=1.15,才能稳定地使用gorm v2读写分离方案,go1.15下载地址: 问题反馈 1.提交问题请在项目顶栏的issue直接添加问题,基本上都是每天处理当天上报的问题。 2.本项目优先关注 仓库的所有问题, github 太卡严重影响效率

GoLang-Gin框架之自动路由封装

Gin框架封装了基础框架,给开发人员带来了很多方便,但是具体项目中,如果只使用Gin框架原生的来开发,还是有些单薄,如Gin的路由,写法比较冗长,如果开发项目,代码量过多,冗余重复代码比较多,看起来逻辑不够清晰,我们经过一些封装可能就比较简单清晰,我们就可以专注于业务逻辑的实现来编码了。

yan_dk的专栏 5638

caxa二次开发实例展示

本人有8年CAXA各产品(如电子图版、工艺图表、PDM等)二次开发经验,参与过国家电网南瑞集团、中石油、龙记集团、欧姆龙集团、港日集团、中集集团、中国五矿、方圆塑机、大连锅炉、金蝶PDM集成CAXA,TEAMCENTER集成CAXA、大连锅炉机械、中国中车等项目的开发,擅长CAXA电子图版、CAXA工艺图表的二次开发,有需要的可以联系我,电话:13169467685、13249738576 Q

hourui800720的专栏 8031

汉字跨越三千年的生命力与数字时代适应性

文字作为文明载体,其演变规律始终遵循实用性与适应性的平衡。汉字作为现存最古老的文字系统,凭借形义结合的六书构造原理,实现了超方言的文化统一功能。在计算机处理方面,五笔输入法与Unicode支持证明了其技术兼容性,而视觉识别效率的先天优势使其在信息时代更具传播效力。从甲骨文识别AI到现代书法设计,汉字系统持续展现强大的文化承载力与技术适应性,这种活态传承为数字人文研究提供了独特样本。

weixin_29058331的博客 355

gin的基础及其简单封装

大家好,我是 Gin。在 Go 语言的 Web 开发领域,我可是一位实力强劲的伙伴呢。我以高性能和简洁高效著称。在处理 HTTP 请求时,我速度飞快,能够轻松应对高并发的场景。无论是小型项目还是大型的企业级应用,我都能游刃有余地发挥作用。我的设计理念强调简洁性。我的 API 简洁明了,易于学习和使用。开发人员可以快速上手,用最少的代码实现强大的功能。我提供了丰富的中间件,可以方便地处理各种常见的 Web 开发任务,如请求日志记录、错误处理、身份验证等。我还具备良好的路由机制。

2301_76439627的博客 924

实验2 存储器设计与实现【计算机组成原理】

实验2 存储器设计与实现【计算机组成原理】

小心星的博客 2401

04 基于Gin框架的项目开发—封装响应和异常处理

本文介绍了基于Gin框架的项目开发中封装响应结果和异常处理的实现方法。

1 1109

光学传播仿真软件:SPEOS_(14).建筑物内光环境仿真

在建筑物内光环境仿真中,材料属性的定义直接影响光的传播和反射效果。SPEOS提供了丰富的材料库,但也可以自定义材料属性以满足特定需求。创建新材料选择Materials->。输入材料名称和类型。配置材料属性选择材料对象,打开属性编辑器。设置反射率、透射率、表面粗糙度和颜色。# 导入SPEOS模块# 创建新材料# 配置材料属性custom_material.set_reflectivity(0.8) # 设置反射率为0.8。

kkchenjj的博客 1251

RK3566/RK3568 Android 11 无操作自动隐藏导航栏、底部上拉显示导航栏

RK3566/RK3568 Android 11 定制大全在系统服务中增加无操作自动隐藏导航栏方法,在上层app动态调用无操作自动隐藏导航栏方法,系统会在5秒无操作后自动隐藏导航栏,隐藏导航栏后从底部上拉可显示导航栏,设备关机和重启后也能继续生效。

qq_23921815的博客 1260

Gin 没有更好,只有最好

Gin闪亮登场,其他都得黯然离场

码刀攻城 2535

069_死区效应对输出电压畸变的补偿思路

死区效应导致逆变器输出电压在过零点出现台阶畸变,引发THD升高。其本质是死区期间续流二极管钳位造成的非线性误差,与电流方向、负载大小、母线电压耦合。补偿需结合前馈(基于电流方向自适应调整偏置)与反馈(抑制残余谐波),关键在于准确判断电流方向(采用滞环滤波避免跳变)、合理设置补偿量(随负载动态调整),并注意补偿位置、极性及限幅防漂移。调试应通过差分探头、FFT频谱等手段验证效果,最终实现全负载范围内的低畸变输出。

2401_88858637的博客 22

探索Gin框架:Golang使用Gin完成文件上传

Go标准库net/http对文件上传已经提供了非常完善的支持,Gin框架在其基础做了封装,使用更加简单便捷。作者:鼠鼠我捏,要死了捏

qq_35716689的博客 37万+

Openclaw接入大模型API,操作本地windows文件

本文介绍了在WSL2环境下配置OpenClaw使用阿里百炼API的方法。主要内容包括:1)确认WSL2安装完成;2)配置阿里百炼API(需注意Qwen3-Max-Thinking为收费模型);3)提供正确的JSON配置格式示例,强调apiKey必须填写真实值;4)说明配置错误需修改Linux配置文件;5)建议通过询问模型信息验证连接成功。后续将介绍如何切换免费API及本地文件访问功能。

qq_27246521的博客 989

go语言实现服务器server端与客户client端即时通信(附完整源码)

go语言实现服务器server端与客户client端即时通信(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 631

Golang gin框架

gin框架学习一、Gin 介绍二、Gin 环境搭建三、golang 程序的热加载四、Gin 框架中的路由五、Gin HTML 模板渲染六、静态文件服务七、路由详解八、Gin 中自定义控制器九、Gin 中间件十、Gin 中自定义Model十一、Gin 文件上传十二、Gin 中的Cookie十三、Gin 中的Session十四、Gin 中使用GORM 操作mysql 数据库十五、原生 SQL 和 SQL 生成器十六、Gin 中使用GORM 实现表关联查询十七、 GORM 中使用事务十八、Gin 中使用go

book_longker的专栏 2万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

探索Gin框架:Golang Gin框架请求参数的获取

我们在专栏的前面几篇文章内讲解了Gin框架的路由配置,服务启动等内容。在我们平常添加路由处理函数之后,就可以在路由处理函数中编写业务处理代码了,但在此之前我们往往需要获取请求参数,本文就详细的讲解下gin获取请求参数常见的几种方式。目录前言传递参数的方式HeaderURLHTTP Body直接获取请求参数获取URL Path中的参数获取URL Query中的参数获取HTTP Body中的参数绑定请求参数绑定Header参数绑定URL Path参数绑定URL Query参数绑定HTTP Body参数。

qq_35716689的博客 37万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

gin框架学习-文件上传

gin框架学习-文件上传

林钟一的博客 6324

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

go进阶(1) gin框架

Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范。

m0_73822222的博客 1956

Golang Gin框架HTTP上传文件

这个函数会返回一个新的 Reader 对象,该对象会在读取请求的正文时自动检查字节数,如果超过指定的最大字节数,则会自动停止读取,返回错误。HTTP协议的文件上传是通过HTTP POST请求实现的,使用multipart/form-data格式将待上传的文件放入请求体中。要实现 Gin 框架中的文件上传进度,在文件上传中,计算已上传的字节数,并将其与文件的总大小进行比较,以确定上传的进度。该代码不能限制文件上传大小,只是设置内存大小,即使文件大小比这个大,也会写入临时文件。

地球流浪猫的博客 2713

Go语言Web框架--Gin介绍和使用

所谓框架 框架一直是敏捷开发中的利器,能让开发者很快的上手并做出应用,甚至有的时候,脱离了框架,一些开发者都不会写程序了。成长总不会一蹴而就,从写出程序获取成就感,再到精通框架,快速构造应用,当这些方面都得心应手的时候,可以尝试改造一些框架,或是自己创造一个。 曾经我以为Python世界里的框架已经够多了,后来发现相比golang简直小巫见大巫。golang提供的net/http库已经很好...

一只IT小小鸟 2万+

[golang gin框架] 15.Gin 商城项目-封装上传图片方法,轮播图的增删改查以及异步修改状态,数量

封装上传图片方法,轮播图的增删改查以及异步修改状态,数量

资深系统架构,深耕高并发研发与 AI 大模型工程化落地。技术栈以 Python (AI/NLP/RAG/Agent) 与 Golang (高并发架构) 为双核心,兼具 PHP 大型应用经验。专注算法落地、复杂系统设计及团队技术赋能 1216

[GoLang]Gin实现文件上传

简单实现了Gin处理单文件和多文件上传的功能

m0_48587804的博客 1414

[golang gin框架] 4.自定义Model以及Gin 文件上传

Gin 自定义 Model,以及Gin文件上传操作

资深系统架构,深耕高并发研发与 AI 大模型工程化落地。技术栈以 Python (AI/NLP/RAG/Agent) 与 Golang (高并发架构) 为双核心,兼具 PHP 大型应用经验。专注算法落地、复杂系统设计及团队技术赋能 1784
上一篇: Gin框架: 控制器, 中间件的分层设计案例
下一篇: Gin框架: Cookie和Session在单体架构和分布式架构下的应用
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值