文件上传、重定向、Gin路由

news2024/9/22 22:02:17

文件上传

单个文件上传

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 main

import (
	"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 MiB
	router.POST("/upload", func(c *gin.Context) {
		// Multipart form
		form, _ := 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) {
    // 指定重定向的URL
    c.Request.URL.Path = "/test2"
    r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{"hello": "world"})
})

【例】

package main

import (
	"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.com
		c.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 main

import (
	"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"})
			// ...
		}
	})

	//NoRoute
	r.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 这个库。
其基本原理就是构造一个路由地址的前缀树。

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

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

相关文章

MySQL学习(索引)

文章目录 基本概念单列索引普通索引&#xff08;index&#xff09;唯一索引&#xff08;unique&#xff09;主键索引 组合索引全文索引&#xff08;fulltext&#xff09;空间索引&#xff08;spatial&#xff09;MySQL存储引擎 基本概念 通过某种算法&#xff0c;构建数据模型&…

云手机的海外原生IP有什么用?

在全球数字化进程不断加快的背景下&#xff0c;企业对网络的依赖程度日益加深。云手机作为一项创新的工具&#xff0c;正逐步成为企业优化网络结构和全球业务拓展的必备。尤其是云手机所具备的海外原生IP功能&#xff0c;为企业进入国际市场提供了独特的竞争优势。 什么是海外原…

高等数学——微分学

1. 一元函数微分学 1.1. 导数概念 1.2. 导数运算 1.3. 导数与几何 2. 多元函数微分学 2.1. 多元函数的极限 2.1.1. 计算 直接代入法 无穷小乘有界 有理化型 等价无穷小型 ……总结 2.1.2. 是否存在 考试中,判断极限是否存在的问题,答案一般都是不存在。因为,证明一个…

视频怎么剪切掉一部分?6款视频剪切软件,零基础也能快速学会!

您是否也曾遇到了这样的一个问题&#xff1a;在录制完视频之后&#xff0c;发现视频中存在一些多余或者不想要的片段&#xff0c;想要将它剪切掉却不知道具体要怎么操作&#xff1f;别担心&#xff0c;几乎所有视频都会需要这样的调整才能更加出色。如果您是刚入门的视频剪辑初…

MATLAB中多张fig图合并为一个图

将下列两个图和为一个图 打开查看-----绘图浏览器 点击第一幅图中曲线右键复制&#xff0c;到第二幅图中粘贴即可完成

设计模式之组合模式例题

答案&#xff1a;C A 知识点&#xff1a;组合模式的意图&#xff1a;将对象组合成树型结构以表示“整体-部分”的层次结构&#xff0c;使得用户对单个对象和组合对象的使用具有一致性

TMS320F28335的RS232 通信实验

TMS320F28335 内部含有非常多的通信接口,其中串口是通信接口中应用 非常广泛之一,开发板上集成了一个 RS232 模块,其中串口就是接在 F28335 芯 片的 SCIA 接口。 F28335 通过 SCIA 实现与 PC 机对话,F28335 的 SCIA 收到 PC 机发来的数据后 原封不动的返回给 PC 机显示,定…

分布式项目-开盒头条

开盒头条 前言 只懂得技术理论是远远不够的&#xff0c;还需要熟练掌握很多业务功能逻辑的实现&#xff0c;这样才能真正的提高自己的开发水平。因此&#xff0c;我新开了这个专栏&#xff0c;专门做项目&#xff0c;教给大家很多业务功能实现的逻辑以及在实现这些业务功能时…

双向链表-

链表特性&#xff1a;带头/不带头 循环/非循环 --->排列组合后&#xff0c;共有8种链表结构 一.双向链表的定义 前一个节点存了后一个节点的地址&#xff0c;后一个节点也存了前一个节点的地址&#xff0c;即循环链表 二.代码解析 //双向链表 //与非循环链表区别&#…

基于SpringBoot+Vue+MySQL的医院信息管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 在当今社会&#xff0c;随着医疗服务需求的不断增长和医疗信息化的快速发展&#xff0c;提升医院管理效率和服务质量成为了医疗行业的核心需求。传统的医院管理模式面临着效率低下、资源分配不均、患者就医体验差等问题。为了应…

react hooks--useReducer

概述 很多人看到useReducer的第一反应应该是redux的某个替代品&#xff0c;其实并不是 ◼ useReducer仅仅是useState的一种替代方案&#xff1a;  在某些场景下&#xff0c;如果state的处理逻辑比较复杂&#xff0c;我们可以通过useReducer来对其进行拆分&#xff1b; 或…

分布式事务详细笔记:什么是分布式事务--Seata--XA模式--AT模式

目录 1.分布式事务 1.1.什么是分布式事务 1.2.认识Seata 1.3.部署TC服务 1.3.1.准备数据库表 1.3.2.准备配置文件 1.3.3.Docker部署 1.4.微服务集成Seata 1.4.1.引入依赖 1.4.2.改造配置 1.4.3.添加数据库表 1.5.XA模式 1.5.1.两阶段提交 1.5.2.Seata的XA模型 1…

【C++】C++入门概念(二)

引用 概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。 比如&#xff1a;李逵&#xff0c;在家称为"铁牛"&#xff0c;江湖上人称"黑旋…

C++从入门到起飞之——多态 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1. 多态的概念 2. 多态的定义及实现 2.1 多态的构成条件 2.1.1 实现多态还有两个必须重要条件&…

数据结构-树和二叉树

树 和 二叉树 1.树的概念 树 tree 是n(n>0)个节点的有限集 在任意的一个非空树中 (1)有且仅有一个特定的被称为 根(root) 的节点 (2)当n>1时, 其余的节点可分为m(m>0)个互不相交的有限集T1, T2, T3, .... …

Java 入门指南:JVM(Java虚拟机)—— Java 类加载器详解

类加载器 类加载器&#xff08;Class Loader&#xff09;是 Java 虚拟机&#xff08;JVM&#xff09;的一部分&#xff0c;它的作用是将类的字节码文件&#xff08;.class 文件&#xff09;从磁盘或其他来源加载到 JVM 中。类加载器负责查找和加载类的字节码文件&#xff0c;并…

HTML和CSS做一个无脚本的手风琴页面(保姆级)

一、前言 使用HTML和CSS做一个无脚本的手风琴页面。让知识以自己喜欢的方式进入脑子&#xff0c;适用于很多场景&#xff0c;比如以下&#xff1a; 【注&#xff1a;图片源自百度】 二、HTML框架 使用外部样式表&#xff0c;将CSS文件用link标签引入 整体框架如下图&#x…

基于微信小程序的游泳馆管理系统--论文源码调试讲解

2 关键技术介绍 2.1 SSM框架 开发信息管理系统的主流框架是SSM&#xff08;Spring Spring MVC MyBatis&#xff09;&#xff0c;SSM框架web层使用Spring MVC框架&#xff0c;使传输前后端数据变得简单&#xff1b;对于业务层使用Spring作为轻量级控制反转和面向切面的容器框…

Leetcode面试经典150题-39.组合总数

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选取 。如…

基于Ambari搭建hadoop生态圈+Centos7安装教程

当我们学习玩搭建hadoop的时候&#xff0c;未免也会遇见很多繁琐的事情&#xff0c;比如很多错误&#xff0c;需要解决。在以后公司&#xff0c;也不可能让你一个一个搭建hadoop&#xff0c;成千上万的电脑&#xff0c;你在一个个搭建&#xff0c;一个个报错&#xff0c;而且每…