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

Java转Go日记(五十四):gin路由

1. 基本路由

  • gin 框架中采用的路由库是基于httprouter做的

  • 地址为:https://github.com/julienschmidt/httprouter

package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "hello word")})r.POST("/xxxpost",getting)r.PUT("/xxxput")//监听端口默认为8080r.Run(":8000")
}

2. Restful风格的API

  • gin支持Restful风格的API

  • 即Representational State Transfer的缩写。直接翻译的意思是"表现层状态转化",是一种互联网应用程序的API设计理念:URL定位资源,用HTTP描述操作

1.获取文章 /blog/getXxx Get blog/Xxx 

2.添加 /blog/addXxx POST blog/Xxx

3.修改 /blog/updateXxx PUT blog/Xxx

4.删除 /blog/delXxxx DELETE blog/Xxx

3. API参数

  • 可以通过Context的Param方法来获取API参数

  • localhost:8000/xxx/zhangsan

package mainimport ("net/http""strings""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/user/:name/*action", func(c *gin.Context) {name := c.Param("name")action := c.Param("action")//截取/action = strings.Trim(action, "/")c.String(http.StatusOK, name+" is "+action)})//默认为监听8080端口r.Run(":8000")
}

输出结果:

 

 

4. URL参数

  • URL参数可以通过DefaultQuery()或Query()方法获取
  • DefaultQuery()若参数不村则,返回默认值,Query()若不存在,返回空串
  • API ? name=zs
package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/user", func(c *gin.Context) {//指定默认值//http://localhost:8080/user 才会打印出来默认的值name := c.DefaultQuery("name", "枯藤")c.String(http.StatusOK, fmt.Sprintf("hello %s", name))})r.Run()
}

不传递参数输出的结果:

 

传递参数输出的结果:

 

5. 表单参数

  • 表单传输为post请求,http常见的传输格式为四种:
    • application/json
    • application/x-www-form-urlencoded 
    • application/xml
    • multipart/form-data 
  • 表单参数可以通过PostForm()方法获取,该方法默认解析的是x-www-form-urlencoded或from-data格式的参数
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><form action="http://localhost:8080/form" method="post" action="application/x-www-form-urlencoded">用户名:<input type="text" name="username" placeholder="请输入你的用户名">  <br>密&nbsp;&nbsp;&nbsp;码:<input type="password" name="userpassword" placeholder="请输入你的密码">  <br><input type="submit" value="提交"></form>
</body>
</html>
package main//
import ("fmt""net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.POST("/form", func(c *gin.Context) {types := c.DefaultPostForm("type", "post")username := c.PostForm("username")password := c.PostForm("userpassword")// c.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s", username, password, types))c.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s", username, password, types))})r.Run()
}

 输出结果:

 

6. 上传单个文件

  • multipart/form-data格式用于文件上传

  • gin文件上传与原生的net/http方法类似,不同在于gin把原生的request封装到c.Request中

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">上传文件:<input type="file" name="file" ><input type="submit" value="提交"></form>
</body>
</html>
package mainimport ("github.com/gin-gonic/gin"
)func main() {r := gin.Default()//限制上传最大尺寸r.MaxMultipartMemory = 8 << 20r.POST("/upload", func(c *gin.Context) {file, err := c.FormFile("file")if err != nil {c.String(500, "上传图片出错")}// c.JSON(200, gin.H{"message": file.Header.Context})c.SaveUploadedFile(file, file.Filename)c.String(http.StatusOK, file.Filename)})r.Run()
}

效果演示:

 

 

6.1.1. 上传特定文件

有的用户上传文件需要限制上传文件的类型以及上传文件的大小,但是gin框架暂时没有这些函数(也有可能是我没找到),因此基于原生的函数写法自己写了一个可以限制大小以及文件类型的上传函数

package mainimport ("fmt""log""net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.POST("/upload", func(c *gin.Context) {_, headers, err := c.Request.FormFile("file")if err != nil {log.Printf("Error when try to get file: %v", err)}//headers.Size 获取文件大小if headers.Size > 1024*1024*2 {fmt.Println("文件太大了")return}//headers.Header.Get("Content-Type")获取上传文件的类型if headers.Header.Get("Content-Type") != "image/png" {fmt.Println("只允许上传png图片")return}c.SaveUploadedFile(headers, "./video/"+headers.Filename)c.String(http.StatusOK, headers.Filename)})r.Run()
}

7. 上传多个文件

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><form action="http://localhost:8000/upload" method="post" enctype="multipart/form-data">上传文件:<input type="file" name="files" multiple><input type="submit" value="提交"></form>
</body>
</html>
package mainimport ("github.com/gin-gonic/gin""net/http""fmt"
)// gin的helloWorldfunc main() {// 1.创建路由// 默认使用了2个中间件Logger(), Recovery()r := gin.Default()// 限制表单上传大小 8MB,默认为32MBr.MaxMultipartMemory = 8 << 20r.POST("/upload", func(c *gin.Context) {form, err := c.MultipartForm()if err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("get err %s", err.Error()))}// 获取所有图片files := form.File["files"]// 遍历所有图片for _, file := range files {// 逐个存if err := c.SaveUploadedFile(file, file.Filename); err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("upload err %s", err.Error()))return}}c.String(200, fmt.Sprintf("upload ok %d files", len(files)))})//默认端口号是8080r.Run(":8000")
}

效果演示:

 

 

 

8. routes group

  • routes group是为了管理一些相同的URL
package mainimport ("github.com/gin-gonic/gin""fmt"
)// gin的helloWorldfunc main() {// 1.创建路由// 默认使用了2个中间件Logger(), Recovery()r := gin.Default()// 路由组1 ,处理GET请求v1 := r.Group("/v1")// {} 是书写规范{v1.GET("/login", login)v1.GET("submit", submit)}v2 := r.Group("/v2"){v2.POST("/login", login)v2.POST("/submit", submit)}r.Run(":8000")
}func login(c *gin.Context) {name := c.DefaultQuery("name", "jack")c.String(200, fmt.Sprintf("hello %s\n", name))
}func submit(c *gin.Context) {name := c.DefaultQuery("name", "lily")c.String(200, fmt.Sprintf("hello %s\n", name))
}

效果演示:

9. 路由原理

  • httproter会将所有路由规则构造一颗前缀树

  • 例如有 root and as at cn com

 

http://www.xdnf.cn/news/8056.html

相关文章:

  • P1833 樱花
  • 端口号详解(技术向)
  • Java之函数式接口、lambda表达式、stream流操作、Optional容器、方法引用
  • 企业级调度器LVS
  • Java读写分离实战
  • Java SpringBoot 项目中 Redis 存储 Session 具体实现步骤
  • Java阻塞队列(BlockingQueue)的使用:ArrayBlockingQueue类、LinkedBlockingQueue类
  • JVM参数详解与实战案例指南(AI)
  • BurpSuite学习安装
  • MobaXterm 解除只能保存14个session会话限制
  • 篇章十 消息持久化(二)
  • 加密软件对企业安全的帮助
  • 水浒后传-暹罗国建立新国家的故事
  • 影刀Fun叉鸟-2048
  • 【强化学习】PPO如何根据奖励模型调整模型参数
  • 使用 OpenCV 实现哈哈镜效果
  • Python-阶跃函数与激活函数
  • 项目中常用的docker指令
  • 免下载苹果IPA文件重签名工具:快速更换应用名称和BID(Bundle Identifier)的详细教程
  • 【GESP真题解析】第 20 集 GESP 一级 2025 年 3 月编程题 1:图书馆的老鼠
  • 提升搜索效率:深入了解Amazon Kendra的强大功能
  • 内核调试高手养成实战 · Day 2:i.MX8MP 实战调试 Vivante GPU 驱动
  • Spring AI 1.0 GA 正式发布
  • 信号量机制:操作系统中的同步与互斥利器
  • openlayer:11点击地图上省份实现overlay提示省份名称并修改对应所点省份区域颜色
  • c++11的auto关键一篇文章打通:基本用法、常见使用场景、最佳食用指南
  • 小刚说C语言刷题—1153 - 查找“支撑数”
  • Docker面试题(1)
  • MinIO纠删码技术解析:数据冗余与高可用的存储密码
  • 命令行关闭特定端口 命令行关闭端口脚本