第一节- gin参数绑定
目录
[第一节- gin参数绑定](#第一节- gin参数绑定)
ShouldBind
是 gin
框架中的一个方法,用于将请求中的数据绑定到指定的结构体上。
ShouldBind简要概述
功能:
- 它会根据请求的
Content-Type
自动解析请求中的数据,并将其绑定到传入的结构体指针所指向的结构体中。 - 对于
GET
请求,它会尝试从查询参数中解析数据;对于POST
请求,它会根据Content-Type
进行不同的解析,例如application/x-www-form-urlencoded
或application/json
等。
使用场景:
- 当你需要从客户端请求中提取数据并存储到结构体中时,使用
ShouldBind
可以方便地将请求中的数据映射到结构体的字段上。 - 它会自动处理数据类型的转换,将请求中的字符串数据转换为结构体字段对应的类型。
可能的错误:
- 如果请求中的数据无法正确解析或转换为结构体字段的类型,
ShouldBind
会返回错误。 - 例如,如果请求中某个字段的值无法转换为结构体中相应字段的类型(如将字符串 "abc" 转换为
int
类型),会导致绑定失败并返回错误。
实例代码
Go
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
// 定义结构体
type UserInfo struct {
UserName string `form:"username"`
Password string `form:"password"`
}
func main() {
r := gin.Default()
r.GET("/user", func(c *gin.Context) {
var u UserInfo
err := c.ShouldBind(&u)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
} else {
fmt.Printf("u:%#v\n", u)
c.JSON(http.StatusOK, gin.H{
"username": u.UserName,
"password": u.Password,
})
}
})
r.Run(":1205")
}
效果展示
第二节-gin文件上传
选择要上传的文件
Go
// 处理 POST 请求到 /upload 路径
r.POST("/upload", func(c *gin.Context) {
// 从请求中获取名为 f1 的文件
f, err := c.FormFile("f1")
if err != nil {
// 记录错误信息
log.Printf("Error retrieving file: %v", err)
// 返回错误响应
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to retrieve file",
})
return
}
// 验证文件大小,假设限制文件大小为 5MB
if f.Size > 1024*1024*5 {
// 记录文件大小超出限制的错误信息
log.Printf("File size too large: %v", f.Size)
// 返回错误响应
c.JSON(http.StatusBadRequest, gin.H{
"error": "File size exceeds limit",
})
return
}
// 验证文件类型,假设只允许 JPEG 和 PNG
if f.Header.Get("Content-Type") != "image/jpeg" && f.Header.Get("Content-Type") != "image/png" {
// 记录文件类型错误信息
log.Printf("Invalid file type: %v", f.Header.Get("Content-Type"))
// 返回错误响应
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid file type",
})
return
}
// 构建保存文件的目标路径
dst := path.Join("./", f.Filename)
// 保存上传的文件
if err := c.SaveUploadedFile(f, dst); err != nil {
// 记录保存文件时的错误信息
log.Printf("Error saving file: %v", err)
// 返回错误响应
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to save file",
})
return
}
// 返回成功响应
c.JSON(http.StatusOK, gin.H{
"status": "ok",
})
})
对上传的文件进行相对应的操作。
选择要上传的文件。
效果展示
代码部分
因为前端部分较为简单,在这里就不再进行展示了。
Go
package main
import (
"log"
"net/http"
"path"
"github.com/gin-gonic/gin"
)
func main() {
// 创建一个默认的 gin 路由
r := gin.Default()
// 加载 index.html 文件
r.LoadHTMLFiles("./index.html")
// 处理 GET 请求到 /index 路径
r.GET("/index", func(c *gin.Context) {
// 渲染 index.html 文件
c.HTML(http.StatusOK, "index.html", nil)
})
// 处理 POST 请求到 /upload 路径
r.POST("/upload", func(c *gin.Context) {
// 从请求中获取名为 f1 的文件
f, err := c.FormFile("f1")
if err != nil {
// 记录错误信息
log.Printf("Error retrieving file: %v", err)
// 返回错误响应
c.JSON(http.StatusBadRequest, gin.H{
"error": "Failed to retrieve file",
})
return
}
// 验证文件大小,假设限制文件大小为 5MB
if f.Size > 1024*1024*5 {
// 记录文件大小超出限制的错误信息
log.Printf("File size too large: %v", f.Size)
// 返回错误响应
c.JSON(http.StatusBadRequest, gin.H{
"error": "File size exceeds limit",
})
return
}
// 验证文件类型,假设只允许 JPEG 和 PNG
if f.Header.Get("Content-Type") != "image/jpeg" && f.Header.Get("Content-Type") != "image/png" {
// 记录文件类型错误信息
log.Printf("Invalid file type: %v", f.Header.Get("Content-Type"))
// 返回错误响应
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid file type",
})
return
}
// 构建保存文件的目标路径
dst := path.Join("./", f.Filename)
// 保存上传的文件
if err := c.SaveUploadedFile(f, dst); err != nil {
// 记录保存文件时的错误信息
log.Printf("Error saving file: %v", err)
// 返回错误响应
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to save file",
})
return
}
// 返回成功响应
c.JSON(http.StatusOK, gin.H{
"status": "ok",
})
})
// 启动服务器,监听 1205 端口
r.Run(":1205")
}
第三节-gin请求重定向
注意此处请求的是ddd
回车之后
ddd变成了a
仔细观察后端部分的代码,不难看出,访问ddd的时候,跳转到了a,访问a的时候跳转到了b,所以会打印出b中存放的信息。也就是上述效果中展示的样子。
第四节-gin路由和路由组
Any用法
Any可以匹配任何形式的请求,这里因为没有postman所以没有对其他形式的请求进行测试,大家可以自行使用postman进行测试。
NoRoute
当没有对应的请求的时候,会进入到这一函数,如果没有进行定义就会出现404错误的页面。这里也只是对404页面进行了一下自定义操作。
路由组
路由组
路由组可以嵌套路由组
路由组可以添加中间件
路由组可以添加路由
路由组可以添加静态文件
路由组可以添加模板
路由组可以添加重定向
路由组可以添加错误处理
路由组可以添加自定义渲染器
仔细观察这三个图片的url不难看出都是voide开头的,因此我们可以将它们分成一个组来进行汇总一下。将他们的公共前缀提取出来,使得代码看起来不那么繁琐。
这样看起来更加条理清晰,用一个{}进行包括。