表单实体绑定
gin提供了数据结构体和表单提交数据绑定功能,提高表单数据获取的效率。
type UserRegister struct{
Username string `form:"username" json:"username" binding:"required"`
Password string `form:"password" json:"password" binding:"required"`
Phone string `form:"phone" json:"phone" binding:"required"`
}
创建结构体用来接收数据,通过 tag标签 设置每个字段对应的form表单,或者json中的属性名,binding属于设置属性是否是必须。
GET
package main
import (
"fmt"
"log"
"github.com/gin-gonic/gin"
)
type Student struct{
Name string `form:"name"`
Classes string `form:"classes"`
}
func main(){
engine:=gin.Default()
engine.GET("/hello",func(c *gin.Context) {
fmt.Println(c.FullPath())
var student Student
//在查询字符串里搜索
err := c.ShouldBindQuery(&student)
if err!=nil{
log.Fatal(err.Error())
}
fmt.Println(student)
c.Writer.WriteString(student.Name+"登录了")
})
engine.Run()
}
POST
package main
import (
"fmt"
"log"
"github.com/gin-gonic/gin"
)
type UserRegister struct{
Username string `form:"username" json:"username" binding:"required"`
Password string `form:"password" json:"password" binding:"required"`
Phone string `form:"phone" json:"phone" binding:"required"`
}
func main(){
engine:=gin.Default()
engine.POST("/hello",func(c *gin.Context) {
fmt.Println(c.FullPath())
var user UserRegister
//可接受多种形式的参数,比如查询字符串、表单提交、JSON等
err := c.ShouldBind(&user)
if err!=nil{
log.Fatal(err.Error())
}
fmt.Println(user)
c.Writer.WriteString(user.Username+"注册了")
})
engine.Run()
}
返回数据格式
JSON
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main(){
engine:=gin.Default()
engine.GET("/hellojson",func(c *gin.Context) {
fullPath:="请求路径"+c.FullPath()
fmt.Println(fullPath)
//缩写为 gin.H{}
c.JSON(200,map[string]interface{}{
"code":1,
"message":"OK",
"data":fullPath,
})
})
engine.GET("/jsonstruct",func(c *gin.Context) {
fullPath := "请求路径"+c.FullPath()
fmt.Println(fullPath)
resp:=Response{
Code:1,
Message: "OK",
Data: fullPath,
}
//func (*gin.Context).JSON(code int, obj interface{})
//因为 JSON 第二个参数是一个接口,所以要取地址&
c.JSON(200,&resp)
})
engine.Run()
}
type Response struct{
Code int
Message string
Data interface{}
}
Html
项目目录
main.go
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func main(){
r:=gin.Default()
//配置加载静态 Html 的目录
r.LoadHTMLGlob("./html/*")
//配置静态资源的目录
//html端的映射路径 //实际路径
r.Static("/img", "./img")
r.GET("/html",func(c *gin.Context) {
fullPath:="请求路径"+c.FullPath()
fmt.Println(fullPath)
//返回Html
// 对于设置的静态文件目录的路径 返回的对象接口
c.HTML(http.StatusOK,"index.html",gin.H{
"fullPath":fullPath,
"title":"Gin 教程",
})
})
r.Run()
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.title}}</title>
</head>
<body>
Gin 教程
<br/>
当前访问路由为:{{.fullPath}}
<img src="/img/logo.jpg" alt="">
</body>
</html>
如果出现了panic: html/template: pattern matches no files: ./html/*的问题,注意当前项目打开的路径,如果go文件不在根目录,跳转到go文件所在的目录在执行 go run main.go
文件上传
单个文件上传
r.POST("/upload",func(c *gin.Context) {
//限制文件大小
r.MaxMultipartMemory=8<<20 //8MB
//表单取文件
file,_:=c.FormFile("file")
log.Println(file.Filename)
//传到项目根目录,名字就用本身的
c.SaveUploadedFile(file,file.Filename)
c.String(200,fmt.Sprintf("%s upload!",file.Filename))
})
多个文件上传
r.POST("/upload",func(c *gin.Context) {
//限制文件大小
r.MaxMultipartMemory=8<<20 //8MB
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()))
}
c.String(200,fmt.Sprintf("%s upload!\n",file.Filename))
}
})
重定向
r.GET("/redirect",func(c *gin.Context) {
//支持内部和外部重定向
c.Redirect(http.StatusMovedPermanently,"https://www.baidu.com")
})
同步异步
- goroutine 机制可以方便的实现异步处理
- 在启动新的 goroutine时,不应该使用原始上下文,必须使用它的只读副本
//异步
r.GET("/long_async",func(c *gin.Context) {
//需要一个副本
copyContext:=c.Copy()
//异步处理
go func () {
time.Sleep(3*time.Second)
log.Println("异步执行:"+copyContext.Request.URL.Path)
}()
})
//同步
r.GET("/long_sync",func(c *gin.Context) {
time.Sleep(3*time.Second)
log.Println("同步执行:"+c.Request.URL.Path)
})