当前位置: 首页 > news >正文

文件上传、重定向、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 文件上传前端页面代码&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><title>index</title> </head> <body> <form action"/upload" method"post"…...

躺平成长:微信小程序运营日记第二天

在进行属于生活的开源之后&#xff0c;自己更加感受到自己存在的渺茫&#xff0c;同时更加开始深刻领会&#xff0c;开源的重要性&#xff0c;在开源&#xff0c;开放&#xff0c;创造&#xff0c;再创新的思维模式下&#xff0c;不发布八部金刚功相关的训练视频&#xff0c;自…...

三分钟速览:Node.js 版本差异与关键特性解析

Node.js 是一个广泛使用的 JavaScript 运行时环境&#xff0c;允许开发者在服务器端运行 JavaScript 代码。随着技术的发展&#xff0c;Node.js 不断推出新版本&#xff0c;引入新特性和改进。了解不同版本之间的差异对于开发者来说至关重要。以下是一个快速指南&#xff0c;帮…...

git创建新分支

git创建新分支 1.先在gitLab上New branch. 2.本地右键git小乌 - /切换/检出-创建新分支&#xff0c;分支名称和上一步创建的一样。 最后记得改个文件提交下&#xff0c;看看gitLab上是否提交成功。...

Chip-seq数据分析处理流程

一、处理过程 要处理 SRR14879780 的 ChIP-seq 数据并进行基序分析&#xff08;包括比对到参考基因组 hg38.fasta 和峰值调用&#xff09;&#xff0c;你可以按照以下步骤操作&#xff0c;并使用相应的代码。每个步骤会涉及一些常用的生物信息学工具&#xff0c;如 FastQC、Tr…...

spring boot3.2.x与spring boot2.7.x对比

Spring Boot 3.2.x 相比 Spring Boot 2.7.x 带来了许多重要的变化、新特性以及性能改进。这些新功能不仅提升了开发者的效率&#xff0c;还优化了应用的性能和安全性。以下是两者的主要差异、优势以及使用说明&#xff1a; 1. JDK 17 支持 Spring Boot 2.7.x 支持 JDK 8 至 J…...

Vue2(十三):路由

一、路由的简介 vue-rooter&#xff1a;是vue的一个插件库&#xff0c;专门用来实现SPA应用 1.对SPA应用的理解 1、单页 Web 应用&#xff08;single page web application&#xff0c;SPA&#xff09;。 2、整个应用只有一个完整的页面 index.html。 3、点击页面中的导航链…...

Java并发:互斥锁,读写锁,公平锁,Condition,StampedLock

阅读本文之前可以看一看 Java 多线程基础&#xff1a; Java&#xff1a;多线程&#xff08;进程线程&#xff0c;线程状态&#xff0c;创建线程&#xff0c;线程操作&#xff09; Java&#xff1a;多线程&#xff08;同步死锁&#xff0c;锁&原子变量&#xff0c;线程通信&…...

在 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讲]:数据库日志与审计详解:从错误日志到审计日志的配置与使用

全文目录&#xff1a; 前言7.3 日志与审计1. 日志类型与配置1.1 错误日志&#xff08;Error Log&#xff09;配置错误日志使用场景案例演示 1.2 慢查询日志&#xff08;Slow Query Log&#xff09;配置慢查询日志使用场景案例演示 1.3 查询日志&#xff08;General Query Log&a…...

网关的作用及其高可用性设计详解

引言 在现代分布式系统架构中&#xff0c;网关&#xff08;Gateway&#xff09;是一个关键组件。它作为客户端与后端服务之间的桥梁&#xff0c;不仅提供了请求路由、负载均衡、安全认证、流量控制等功能&#xff0c;还能够保护后端服务的安全和稳定性。网关的设计和高可用性对…...

Vortex GPGPU的github流程跑通与功能模块波形探索

文章目录 前言一、跟着官方文档走一遍二、cache子模块的波形仿真2.1 必要的文件内容解释2.2 cache子模块波形仿真——目前环境没啥问题了&#xff0c;就vcd因为配置问题出不来 总结 前言 看了那么久的verilog代码和文档&#xff0c;但还是没怎么接触过Vortex GPGPU全流程跑通与…...

10.2 Linux_并发_进程相关函数

创建子进程 函数声明如下&#xff1a; pid_t fork(void); 返回值&#xff1a;失败返回-1&#xff0c;成功返回两次&#xff0c;子进程获得0(系统分配)&#xff0c;父进程获得子进程的pid 注意&#xff1a;fork创建子进程&#xff0c;实际上就是将父进程复制一遍作为子进程&…...

【深度学习基础模型】玻尔兹曼机BM|受限玻尔兹曼机RBM|深度置信网络DBN详细理解并附实现代码。

【深度学习基础模型】玻尔兹曼机Boltzmann machines (BM)|受限玻尔兹曼机Restricted Boltzmann machines (RBM)|深度置信网络Deep belief networks (DBN)详细理解并附实现代码。 【深度学习基础模型】玻尔兹曼机Boltzmann machines (BM)|受限玻尔兹曼机Restricted Boltzmann m…...

滑动窗口->dd爱框框

1.题目&#xff1a; 2.题解&#xff1a; 2.1为什么用滑动窗口优化&#xff1a; 因为元素都是大于0的 所以&#xff1a;当找到大于等于x的值时&#xff0c;right可以不用返回 两个指针都往后走&#xff1b;因此可以使用滑动窗口优化暴力解法 2.2&#xff1a;滑动窗口具体使用步…...

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 理解条件控制 在日常生活中&#xff0c;我们常喜欢说如果, "如果怎么样&#xff0c;那么就会怎么样"。"如果&qu…...

使用Qt实现实时数据动态绘制的折线图示例

基于Qt的 QChartView 和定时器来动态绘制折线图。它通过动画的方式逐步将数据点添加到图表上&#xff0c;并动态更新坐标轴的范围&#xff0c;提供了一个可以实时更新数据的折线图应用。以下是对代码的详细介绍及其功能解析&#xff1a; 代码概述 该程序使用Qt的 QChartView…...

【人人保-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…...

Redis6 多线程模型

优质博文&#xff1a;IT-BLOG-CN 一、单线程的优缺点 对于一个请求操作Redis主要做3件事情&#xff1a;从客户端读取数据/解析、执行Redis命令、回写数据给客户端。所以主线程其实就是把所有操作的这3件事情串行一起执行&#xff0c;因为是基于内存&#xff0c;所以执行速度非…...

Python的异步编程

什么是协程&#xff1f; 协程不是计算机系统提供&#xff0c;程序员人为创造。 协程也可以被称为微线程&#xff0c;是一种用户态内的上下文切换技术。简而言之&#xff0c;其实就是通过一个线程实现代码块相互切换执行。 实现协程有那么几种方法&#xff1a; greenlet&…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...