文件上传、重定向、Gin路由
文件上传
单个文件上传
index.html
文件上传前端页面代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head><title>index</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data"><input type="file" name="f1"><br><input type="submit" value="上传">
</form>
</body>
</html>
main.go
后端gin框架部分代码:
package mainimport ("github.com/gin-gonic/gin""net/http""path"
)func main() {r := gin.Default()r.LoadHTMLFiles("./index.html")r.GET("/index", func(c *gin.Context) {c.HTML(http.StatusOK, "index.html", nil)})r.POST("/upload", func(c *gin.Context) {// 从请求中读取文件f, err := c.FormFile("f1") // 从请求中获取携带的参数一样的if err != nil {c.JSON(http.StatusOK, gin.H{"error": err.Error(),})} else {// 将读取到的文件保存在本地(服务端本地)//dst := fmt.Sprintf("./%s", f.Filename)dst := path.Join("./", f.Filename)c.SaveUploadedFile(f, dst)c.JSON(http.StatusOK, gin.H{"status": "ok",})}})r.Run(":8080")
}

选择1111.jpg点击上传:


多个文件上传
多个文件上传
func main() {router := gin.Default()// 处理multipart forms提交文件时默认的内存限制是32 MiB// 可以通过下面的方式修改// router.MaxMultipartMemory = 8 << 20 // 8 MiBrouter.POST("/upload", func(c *gin.Context) {// Multipart formform, _ := c.MultipartForm()files := form.File["file"]for index, file := range files {log.Println(file.Filename)dst := fmt.Sprintf("C:/tmp/%s_%d", file.Filename, index)// 上传文件到指定的目录c.SaveUploadedFile(file, dst)}c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("%d files uploaded!", len(files)),})})router.Run()
}
请求重定向
HTTP重定向
HTTP 重定向很容易。 内部、外部重定向均支持。
r.GET("/test", func(c *gin.Context) {c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com/")
})
路由重定向
路由重定向,使用 HandleContext:
r.GET("/test", func(c *gin.Context) {// 指定重定向的URLc.Request.URL.Path = "/test2"r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"hello": "world"})
})
【例】
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()// Gin路由r.GET("/index", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"status": "ok",})})// HTTP重定向r.GET("/index1", func(c *gin.Context) {// 跳转到 sogo.comc.Redirect(http.StatusMovedPermanently, "http://www.sogo.com")})// 路由重定向r.GET("/a", func(c *gin.Context) {// 跳转到 /b 对应的路由处理函数c.Request.URL.Path = "/b" // 把请求的URI修改r.HandleContext(c) // 继续后续的处理})r.GET("/b", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "b",})})r.Run(":8080")


Gin路由
普通路由和路由组
r.GET("/index", func(c *gin.Context) {...})
r.GET("/login", func(c *gin.Context) {...})
r.POST("/login", func(c *gin.Context) {...})
此外,还有一个可以匹配所有请求方法的Any方法如下:
r.Any("/test", func(c *gin.Context) {...})
为没有配置处理函数的路由添加处理程序,默认情况下它返回404代码,下面的代码为没有匹配到路由的请求都返回 views/404.html 页面。
r.NoRoute(func(c *gin.Context) {c.HTML(http.StatusNotFound, "views/404.html", nil)})
【例】
package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()// 访问/index的GET请求会走这一条处理逻辑// 路由// 获取数据r.GET("/index", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"method": "GET",})})// 提交数据r.POST("/index", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"method": "POST",})})// 更新数据r.PUT("/index", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"method": "PUT",})})// 删除数据(如果实现的话)r.DELETE("/index", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"method": "DELETE",})})// Any 请求方法的大集合r.Any("/user", func(c *gin.Context) {switch c.Request.Method {case "GET":c.JSON(http.StatusOK, gin.H{"method": "GET"})case http.MethodPost:c.JSON(http.StatusOK, gin.H{"method": "POST"})// ...}})//NoRouter.NoRoute(func(c *gin.Context) {c.JSON(http.StatusNotFound, gin.H{"msg": "liwenzhou.com"})})/*//视频的首页和详情页r.GET("/video/index", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "/video/index",})})r.GET("/video/xx", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "/video/xx",})})//商城的首页和详情页r.GET("/shop/index", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "/shop/index",})})r.GET("/shop/oo", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "/shop/oo",})})*/// 路由组// 把公用的前缀提取出来,创建一个路由组videoGroup := r.Group("/video")videoGroup.GET("/index", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "/video/index",})})videoGroup.GET("/xx", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "/video/xx",})})shopGroup := r.Group("/shop")shopGroup.GET("/index", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "/shop/index",})})shopGroup.GET("/oo", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "/shop/oo",})})r.Run(":9090")
}
路由原理
Gin框架中的路由使用的是 httprouter 这个库。
其基本原理就是构造一个路由地址的前缀树。
相关文章:
文件上传、重定向、Gin路由
文件上传 单个文件上传 index.html 文件上传前端页面代码: <!DOCTYPE html> <html lang"zh-CN"> <head><title>index</title> </head> <body> <form action"/upload" method"post"…...
躺平成长:微信小程序运营日记第二天
在进行属于生活的开源之后,自己更加感受到自己存在的渺茫,同时更加开始深刻领会,开源的重要性,在开源,开放,创造,再创新的思维模式下,不发布八部金刚功相关的训练视频,自…...
三分钟速览:Node.js 版本差异与关键特性解析
Node.js 是一个广泛使用的 JavaScript 运行时环境,允许开发者在服务器端运行 JavaScript 代码。随着技术的发展,Node.js 不断推出新版本,引入新特性和改进。了解不同版本之间的差异对于开发者来说至关重要。以下是一个快速指南,帮…...
git创建新分支
git创建新分支 1.先在gitLab上New branch. 2.本地右键git小乌 - /切换/检出-创建新分支,分支名称和上一步创建的一样。 最后记得改个文件提交下,看看gitLab上是否提交成功。...
Chip-seq数据分析处理流程
一、处理过程 要处理 SRR14879780 的 ChIP-seq 数据并进行基序分析(包括比对到参考基因组 hg38.fasta 和峰值调用),你可以按照以下步骤操作,并使用相应的代码。每个步骤会涉及一些常用的生物信息学工具,如 FastQC、Tr…...
spring boot3.2.x与spring boot2.7.x对比
Spring Boot 3.2.x 相比 Spring Boot 2.7.x 带来了许多重要的变化、新特性以及性能改进。这些新功能不仅提升了开发者的效率,还优化了应用的性能和安全性。以下是两者的主要差异、优势以及使用说明: 1. JDK 17 支持 Spring Boot 2.7.x 支持 JDK 8 至 J…...
Vue2(十三):路由
一、路由的简介 vue-rooter:是vue的一个插件库,专门用来实现SPA应用 1.对SPA应用的理解 1、单页 Web 应用(single page web application,SPA)。 2、整个应用只有一个完整的页面 index.html。 3、点击页面中的导航链…...
Java并发:互斥锁,读写锁,公平锁,Condition,StampedLock
阅读本文之前可以看一看 Java 多线程基础: Java:多线程(进程线程,线程状态,创建线程,线程操作) Java:多线程(同步死锁,锁&原子变量,线程通信&…...
在 Linux 中,要让某一个线程或进程排他性地独占一个 CPU
文章目录 1. CPU 亲和性(CPU Affinity)2. 中断隔离(IRQ Isolation)3. 系统 tickless 模式(NoHZ Mode)4. 实时调度策略5. CPU 隔离(CPU Isolation)和 Full CPU Isolation实现最低的延迟抖动在 Linux 中,要让某一个线程 排他性地独占一个 CPU,并且进一步隔离中断(包括…...
滚雪球学MySQL[7.3讲]:数据库日志与审计详解:从错误日志到审计日志的配置与使用
全文目录: 前言7.3 日志与审计1. 日志类型与配置1.1 错误日志(Error Log)配置错误日志使用场景案例演示 1.2 慢查询日志(Slow Query Log)配置慢查询日志使用场景案例演示 1.3 查询日志(General Query Log&a…...
网关的作用及其高可用性设计详解
引言 在现代分布式系统架构中,网关(Gateway)是一个关键组件。它作为客户端与后端服务之间的桥梁,不仅提供了请求路由、负载均衡、安全认证、流量控制等功能,还能够保护后端服务的安全和稳定性。网关的设计和高可用性对…...
Vortex GPGPU的github流程跑通与功能模块波形探索
文章目录 前言一、跟着官方文档走一遍二、cache子模块的波形仿真2.1 必要的文件内容解释2.2 cache子模块波形仿真——目前环境没啥问题了,就vcd因为配置问题出不来 总结 前言 看了那么久的verilog代码和文档,但还是没怎么接触过Vortex GPGPU全流程跑通与…...
10.2 Linux_并发_进程相关函数
创建子进程 函数声明如下: pid_t fork(void); 返回值:失败返回-1,成功返回两次,子进程获得0(系统分配),父进程获得子进程的pid 注意:fork创建子进程,实际上就是将父进程复制一遍作为子进程&…...
【深度学习基础模型】玻尔兹曼机BM|受限玻尔兹曼机RBM|深度置信网络DBN详细理解并附实现代码。
【深度学习基础模型】玻尔兹曼机Boltzmann machines (BM)|受限玻尔兹曼机Restricted Boltzmann machines (RBM)|深度置信网络Deep belief networks (DBN)详细理解并附实现代码。 【深度学习基础模型】玻尔兹曼机Boltzmann machines (BM)|受限玻尔兹曼机Restricted Boltzmann m…...
滑动窗口->dd爱框框
1.题目: 2.题解: 2.1为什么用滑动窗口优化: 因为元素都是大于0的 所以:当找到大于等于x的值时,right可以不用返回 两个指针都往后走;因此可以使用滑动窗口优化暴力解法 2.2:滑动窗口具体使用步…...
Python从入门到高手4.1节-掌握条件控制语句
目录 4.1.1 理解条件控制 4.1.2 if, elif, else 4.1.3 条件表达式 4.1.4 条件控制可以嵌套 4.1.5 if语句的三元运算 4.1.6 国庆节快乐 4.1.1 理解条件控制 在日常生活中,我们常喜欢说如果, "如果怎么样,那么就会怎么样"。"如果&qu…...
使用Qt实现实时数据动态绘制的折线图示例
基于Qt的 QChartView 和定时器来动态绘制折线图。它通过动画的方式逐步将数据点添加到图表上,并动态更新坐标轴的范围,提供了一个可以实时更新数据的折线图应用。以下是对代码的详细介绍及其功能解析: 代码概述 该程序使用Qt的 QChartView…...
【人人保-注册安全分析报告-无验证方式导致安全隐患】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…...
Redis6 多线程模型
优质博文:IT-BLOG-CN 一、单线程的优缺点 对于一个请求操作Redis主要做3件事情:从客户端读取数据/解析、执行Redis命令、回写数据给客户端。所以主线程其实就是把所有操作的这3件事情串行一起执行,因为是基于内存,所以执行速度非…...
Python的异步编程
什么是协程? 协程不是计算机系统提供,程序员人为创造。 协程也可以被称为微线程,是一种用户态内的上下文切换技术。简而言之,其实就是通过一个线程实现代码块相互切换执行。 实现协程有那么几种方法: greenlet&…...
从DataOperation接口到QuickSort实现:探究适配器模式在算法整合中的应用
1. 适配器模式:解决接口不兼容的桥梁 想象一下你从国外带回来一个三脚插头的电器,但家里的插座都是两孔的。这时候你会怎么做?大多数人会选择买一个转换插头。在编程世界里,适配器模式就是这个万能的"转换插头"。 最近我…...
别再只靠EWSA了!聊聊WPA密码破解的几种姿势与效率对比
WPA密码破解工具全维度评测:从EWSA到Hashcat的实战指南 在无线安全评估领域,WPA/WPA2密码破解始终是绕不开的技术课题。当安全研究员获得合法授权的握手包后,如何高效完成密码恢复任务?市面上既有EWSA这样的老牌图形化工具&#x…...
阴阳师御魂自动刷脚本:5分钟快速上手的智能挂机指南
阴阳师御魂自动刷脚本:5分钟快速上手的智能挂机指南 【免费下载链接】yysScript 阴阳师脚本 支持御魂副本 双开 项目地址: https://gitcode.com/gh_mirrors/yy/yysScript 还在为重复刷御魂副本而感到疲惫吗?yysScript智能挂机脚本是专为《阴阳师》…...
艾尔登法环黑夜君临修改器2026.5.11最新中文汉化版免费下载 转存后自动更新 (看到请立即转存 资源随时失效)
在《艾尔登法环》的庞大世界观下,一款名为《艾尔登法环:黑夜君临》(ELDEN RING NIGHTREIGN)的衍生作品于 2025 年正式登场。它并非单纯的续作或大型 DLC,而是一款基于原作设定、专注于多人协作生存与浓缩化 RPG 体验的…...
别再死记硬背了!用Python+Graphviz把离散数学的图论和关系画出来(附代码)
用PythonGraphviz将离散数学中的抽象概念可视化 离散数学是计算机科学的基础课程之一,但其中的图论、二元关系等概念往往因为高度抽象而让学习者感到困惑。传统的死记硬背方式不仅效率低下,也难以真正理解这些概念的本质。本文将介绍如何利用Python的net…...
【STM32H7实战】HRTIM高分辨率定时器在数字电源与电机控制中的高级应用与HAL库配置
1. HRTIM高分辨率定时器概述 HRTIM(High-Resolution Timer)是STM32H7系列中一个强大的定时器外设,专为数字电源转换、电机控制等高性能实时控制场景设计。相比普通定时器,它的分辨率高达184ps(在400MHz主频下ÿ…...
如何快速掌控Windows浏览器自由:3步掌握EdgeRemover终极系统优化工具
如何快速掌控Windows浏览器自由:3步掌握EdgeRemover终极系统优化工具 【免费下载链接】EdgeRemover A PowerShell script that correctly uninstalls or reinstalls Microsoft Edge on Windows 10 & 11. 项目地址: https://gitcode.com/gh_mirrors/ed/EdgeRem…...
从通信原理到Verilog:一个约束长度7的卷积码编码器是如何炼成的?
从通信原理到Verilog:一个约束长度7的卷积码编码器是如何炼成的? 在数字通信系统的设计中,纠错编码技术如同隐形的守护者,确保数据在嘈杂信道中可靠传输。卷积码因其优异的纠错性能和简洁的编码结构,成为卫星通信、深空…...
保姆级教程:手把手教你下载、解压与解析ILSVRC2015 VID数据集(附Python脚本)
计算机视觉实战:ILSVRC2015 VID数据集处理全流程指南 当你第一次打开ILSVRC2015 VID数据集时,可能会被它的规模吓到——超过100万张图像、数千个视频序列和复杂的XML标注结构。这份指南将带你从零开始,像处理日常项目一样轻松驾驭这个庞然大…...
X-TRACK GPS自行车码表:从硬件选型到系统集成的工程决策与验证
X-TRACK GPS自行车码表:从硬件选型到系统集成的工程决策与验证 【免费下载链接】X-TRACK A GPS bicycle speedometer that supports offline maps and track recording 项目地址: https://gitcode.com/gh_mirrors/xt/X-TRACK 在嵌入式设备开发领域ÿ…...
