gin学习笔记,不仅包含了基本的增删查改外,还包括参数传递,上传下载,模版、session与中间件等,方便收藏自习可用
文章目录
- 获得个请求
- get打印字符串
- get请求xml
- get请求跳转
- http方法
- 路由
- 可以通过Context的Param方法来获取API参数
- 可以通过DefaultQuery()或Query()方法获取
- 可以通过GetQuery()与Query()方法获取
- 可以通过BindQuery
- 可以通过shouldBindQuery()传递
- QueryMap进行参数传递
- 结构体有map进行传递
- 表单参数传递
- 路径参数传递
- 上传一个文件
- 上传,对文件进行保存
-
- [routes group](#routes group)
- [404 not found](#404 not found)
- json数据解析和绑定
- 表单数据解析和绑定
- url数据绑定
- 各种数据格式的响应
- html模板渲染
- 静态资源文件进行渲染
- 模版取消转义
- go重定向
- cookie
- 多session
- [redis Session固化存储](#redis Session固化存储)
- 异步执行与同步执行
- 中间件
- 全局中间件
- 局部中间件
获得个请求
go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
//r.Get("/hello")
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "hello world",
})
})
err := r.Run(":8080")
if err != nil {
panic(err)
}
}
get打印字符串
go
type User struct {
Id int64 `form:"id" json:"id" uri:"id"`
Name string `form:"name" json:"name" uri:"name"`
Address []string `form:"address" binding:"required" json:"address" uri:"address"`
AddressMap map[string]string `form:"addressMap" json:"addressMap" uri:"addressMap"`
}
func main() {
r := gin.Default()
r.GET("/user/save", func(c *gin.Context) {
c.String(http.StatusOK, "this is %s", "ms string value")
})
r.Run(":8081")
}
get请求xml
go
type User struct {
Id int64 `form:"id" json:"id" uri:"id" xml:"id"`
Name string `form:"name" json:"name" uri:"name" xml:"name"`
Address []string `form:"address" binding:"required" json:"address" uri:"address" xml:"address"`
AddressMap map[string]string `form:"addressMap" json:"addressMap" uri:"addressMap" xml:"addressMap"`
}
func main() {
r := gin.Default()
r.GET("/user/save", func(c *gin.Context) {
id := c.Query("id")
name := c.Query("name")
c.XML(http.StatusOK, gin.H{"id": id, "message": name})
})
r.Run(":8081")
}
get请求跳转
http方法
- GET :get方法请求一个指定资源的表示形式,或使用GET请求应该只被用于获取数据
- POST :POST方法用于将实体提交到指定资源,通常会导致在服务器上的状态变化
- HEAD:HEAD方法请求一个与GET请求的响应相同的响应,但没有响应体
- PUT:PUT方法用请求有效载荷替换目标资源的所有当前表示
- DELETE : DELETE 方法删除指定的资源
路由
go
func main() {
r := gin.Default()
//r.Get("/hello")
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "hello world",
})
})
r.GET("/get", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "hello world",
})
})
r.POST("/save", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "save",
})
})
r.PUT("/put", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "put",
})
})
r.DELETE(
"/delete", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "hello DELETE",
})
})
r.Any(
"/Any", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "hello Any",
})
})
r.GET("/user/find/:id", func(ctx *gin.Context) {
ctx.JSON(200, ctx.Param("id"))
})
r.GET("/u/*Path", func(ctx *gin.Context) {
ctx.JSON(200, ctx.Param("Path"))
})
v1 := r.Group("/v1")
{
v1.GET("find", func(ctx *gin.Context) {
ctx.JSON(200, gin.H{
"message": "find",
})
})
}
v2 := r.Group("/v2")
{
v2.GET("find", func(ctx *gin.Context) {
ctx.JSON(200, gin.H{
"message": "find",
})
})
}
err := r.Run(":8080")
if err != nil {
panic(err)
}
}
可以通过Context的Param方法来获取API参数
go
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)
})
//r.POST("/xxxpost", getting)
r.Run(":8000")
}
可以通过DefaultQuery()或Query()方法获取
传个localhost:8080/user?name=zhangsan
go
func main() {
r := gin.Default()
r.GET("/user", func(c *gin.Context) {
name := c.DefaultQuery("name", "枯藤")
c.String(http.StatusOK, "Hello %s", name)
})
r.Run(":8080")
}
可以通过GetQuery()与Query()方法获取
go
func main() {
r := gin.Default()
//r.Get("/hello")
r.GET("/user/save", func(c *gin.Context) {
id := c.Query("id")
name := c.Query("name")
addr, ok := c.GetQuery("addr")
c.JSON(200, gin.H{
"id": id,
"name": name,
"addr": addr,
"errs": ok,
})
})
err := r.Run(":8080")
if err != nil {
panic(err)
}
}
可以通过BindQuery
go
type User struct {
Id int64 `form:"id"`
Name string `form:"name"`
}
func main() {
r := gin.Default()
//r.Get("/hello")
r.GET("/user/save", func(c *gin.Context) {
var user User
err := c.BindQuery(&user)
if err != nil {
log.Fatalln(err)
}
c.JSON(http.StatusOK, user)
})
errs := r.Run(":8080")
if errs != nil {
panic(errs)
}
}
可以通过shouldBindQuery()传递
go
type User struct {
Id int64 `form:"id"`
Name string `form:"name"`
Address []string `form:"address" binding:"required"`
}
func main() {
r := gin.Default()
//r.Get("/hello")
r.GET("/user/save", func(c *gin.Context) {
var user User
c.ShouldBindQuery(&user)
c.JSON(http.StatusOK, user)
})
errs := r.Run(":8080")
if errs != nil {
panic(errs)
}
}
QueryMap进行参数传递
go
type User struct {
Id int64 `form:"id"`
Name string `form:"name"`
Address []string `form:"address" binding:"required"`
}
func main() {
r := gin.Default()
//r.Get("/hello")
r.GET("/user/save", func(c *gin.Context) {
addressMap := c.QueryMap("addressMap")
c.JSON(200, addressMap)
})
errs := r.Run(":8080")
if errs != nil {
panic(errs)
}
}
go
localhost:8080/user/save?addressMap[c]=d&addressMap[d]=a
{
"c": "d",
"d": "a"
}
结构体有map进行传递
go
type User struct {
Id int64 `form:"id"`
Name string `form:"name"`
Address []string `form:"address" binding:"required"`
AddressMap map[string]string `form:"addressMap"`
}
func main() {
r := gin.Default()
//r.Get("/hello")
r.GET("/user/save", func(c *gin.Context) {
var user User
c.ShouldBind(&user)
user.AddressMap = c.QueryMap("addressMap")
c.JSON(200, user)
})
_ = r.Run(":8080")
}
表单参数传递
html
<!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>
密 码:<input type="password" name="userpassword" place
holder="请输入你的密码"> <br>
<input type="submit" value="提交">
</form>
</body>
</html>
用一个表单进行参数传递
go
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))
})
r.Run(":8080")
}
关于表单的其他参数
go
type User struct {
Id int64 `form:"id"`
Name string `form:"name"`
Address []string `form:"address" binding:"required"`
AddressMap map[string]string `form:"addressMap"`
}
func main() {
r := gin.Default()
//r.Get("/hello")
r.POST("/user/save", func(c *gin.Context) {
id := c.PostForm("id")
name := c.PostForm("name")
address := c.PostFormArray("address")
addressMap := c.PostFormMap("addressMap")
c.JSON(200, gin.H{
"code": 200,
"msg": "success",
"id": id,
"name": name,
"addressMap": addressMap,
"addressSlice": address,
})
})
r.Run(":8081")
}
也可以用绑定获取表单传过来的参数
go
type User struct {
Id int64 `form:"id"`
Name string `form:"name"`
Address []string `form:"address" binding:"required"`
AddressMap map[string]string `form:"addressMap"`
}
func main() {
r := gin.Default()
//r.Get("/hello")
r.POST("/user/save", func(c *gin.Context) {
var user User
c.ShouldBind(&user)
addressMap := c.PostFormMap("addressMap")
user.AddressMap = addressMap
c.JSON(200, user)
})
r.Run(":8081")
}
也可以用json形式
go
type User struct {
Id int64 `form:"id" json:"id"`
Name string `form:"name" json:"name"`
Address []string `form:"address" binding:"required" json:"address"`
AddressMap map[string]string `form:"addressMap" json:"addressMap"`
}
func main() {
r := gin.Default()
r.POST("/user/save", func(c *gin.Context) {
var user User
c.ShouldBindJSON(&user)
c.JSON(200, user)
})
r.Run(":8081")
}
路径参数传递
go
在这里插入代码片
上传一个文件
html
<!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" />
<button type="submit">上传</button>
</form>
</body>
</html>
go代码
go
func main() {
r := gin.Default()
r.MaxMultipartMemory = 8 << 20 // 8 MB
r.POST("/upload", func(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
log.Printf("上传文件时发生错误: %v", err)
c.String(500, "上传图片出错: %v", err)
return
}
// 检查文件类型
if !strings.HasPrefix(file.Header.Get("Content-Type"), "image/") {
c.String(400, "只允许上传图片文件")
return
}
// 确保上传目录存在
if err := os.MkdirAll("./uploads", os.ModePerm); err != nil {
log.Printf("创建文件夹失败: %v", err)
c.String(500, "创建文件夹失败: %v", err)
return
}
// 保存文件
savePath := "./uploads/" + file.Filename
if err := c.SaveUploadedFile(file, savePath); err != nil {
log.Printf("保存文件时发生错误: %v", err)
c.String(500, "保存文件出错: %v", err)
return
}
c.String(http.StatusOK, "文件上传成功: %s", file.Filename)
})
r.Run(":8080")
}
上传特定文件
go
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 yo get file:%v", err)
}
if headers.Size > 1024*1024*2 {
fmt.Println("文件太大了...")
return
}
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(":8080")
}
上传多个文件
go
func main() {
r := gin.Default()
r.MaxMultipartMemory = 8 << 20
r.POST("/upload", func(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("get error: %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 error:%s", err.Error()))
return
}
}
c.String(200, fmt.Sprintf("upload ok %d files", len(files)))
})
r.Run(":8000")
}
上传,对文件进行保存
go
type User struct {
Id int64 `form:"id" json:"id" uri:"id"`
Name string `form:"name" json:"name" uri:"name"`
Address []string `form:"address" binding:"required" json:"address" uri:"address"`
AddressMap map[string]string `form:"addressMap" json:"addressMap" uri:"addressMap"`
}
func main() {
r := gin.Default()
r.POST("/user/save/:id/:name", func(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
panic(err)
}
value := form.Value
files := form.File
for _, fileArray := range files {
for _, f := range fileArray {
c.SaveUploadedFile(f, "./"+f.Filename)
}
}
c.JSON(200, value)
})
r.Run(":8081")
}
routes group
路由组合
go
func main() {
r := gin.Default()
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(":8080")
}
func login(c *gin.Context) {
name := c.DefaultQuery("name", "jack")
c.String(200, fmt.Sprintf("hello %s %s\n", name, name))
}
func submit(c *gin.Context) {
name := c.DefaultQuery("name", "lily")
c.String(200, fmt.Sprintf("hello %s %s\n", name, name))
}
404 not found
go
func main() {
r := gin.Default()
r.GET("/user", func(c *gin.Context) {
name := c.DefaultQuery("name", "枯藤")
c.String(http.StatusOK, fmt.Sprintf("hello %s", name))
})
r.NoRoute(func(c *gin.Context) {
c.String(http.StatusNotFound, "404 page not found222222222222")
})
r.Run(":8080")
}
json数据解析和绑定
go
type Login struct {
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Password string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}
func main() {
//创建路由
r := gin.Default()
//json绑定
r.POST("loginJSON", func(c *gin.Context) {
var json Login
if err := c.ShouldBindJSON(&json); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if json.User != "root" || json.Password != "123456" {
c.JSON(http.StatusBadRequest, gin.H{"status": "304"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "200"})
})
r.Run(":8080")
}
表单数据解析和绑定
go
type Login struct {
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Password string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}
func main() {
//创建路由
r := gin.Default()
r.POST("/loginForm", func(c *gin.Context) {
var form Login
if err := c.Bind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if form.User != "root" || form.Password != "admin" {
c.JSON(http.StatusBadRequest, gin.H{"error": "304"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "200"})
})
r.Run(":8080")
}
url数据绑定
go
type Login struct {
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Password string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}
func main() {
r := gin.Default()
//json绑定
r.GET("/:user/:password", func(c *gin.Context) {
var login Login
if err := c.ShouldBindUri(&login); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
//判断用户名密码是否正确
if login.User != "root" || login.Password != "123456" {
c.JSON(http.StatusBadRequest, gin.H{"error": "304"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "200"})
})
r.Run(":8080")
}
各种数据格式的响应
go
func main() {
//创建路由
r := gin.Default()
//1.json
r.GET("/someJSON", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "someJSON", "status": 200})
})
//结构体响应
r.GET("/someStruct", func(c *gin.Context) {
var msg struct {
Name string
Message string
Number int
}
msg.Name = "root"
msg.Message = "message"
msg.Number = 124
c.JSON(200, msg)
})
r.GET("/someXML", func(c *gin.Context) {
c.XML(200, gin.H{"message": "abc"})
})
//yaml响应
r.GET("/someYAML", func(c *gin.Context) {
c.YAML(200, gin.H{"message": "zhangsan"})
})
//5. protobuf 格式
r.GET("/someProtobuf", func(c *gin.Context) {
reps := []int64{int64(1), int64(2)}
label := "label"
data := &protoexample.Test{
Label: &label,
Reps: reps,
}
c.ProtoBuf(200, data)
})
r.Run(":8080")
}
html模板渲染
目录:
go
func main() {
//创建路由
r := gin.Default()
r.LoadHTMLGlob("tem/*")
r.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{
"title": "我是测试",
"ce": "123456",
})
})
r.Run(":8080")
}

go
{{ define "user/index.html" }}
<!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>{{.title}}</title>
</head>
<body>
fgkjdskjdsh{{.address}}
</body>
</html>
{{ end }}
go
func main() {
//创建路由
r := gin.Default()
r.LoadHTMLGlob("tem/**/*")
r.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "user/index.html", gin.H{
"title": "我是测试",
"address": "www.61mh.com",
})
})
r.Run(":8080")
}
模板嵌套
header.html
html
{{define "public/header"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{.title}}</title>
</head>
<body>
{{end}}
footer.html
html
{{define "public/footer"}}
</body>
</html>
{{end}}
index.html
html
{{ define "user/index.html" }}
{{template "public/header" .}}
fgkjdskjdsh{{.address}}
{{template "public/footer" .}}
{{ end }}
go
func main() {
//创建路由
r := gin.Default()
r.LoadHTMLGlob("tem/**/*")
r.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "user/index.html", gin.H{
"title": "Goland Projects",
"address": "www.51mh.com",
})
})
r.Run(":8080")
}
静态资源文件进行渲染
go
func main() {
r := gin.Default()
//r.LoadHTMLFiles("./templates/index.tmpl", "./templates/user.tmpl")
r.SetFuncMap(template.FuncMap{
"safe": func(str string) template.HTML {
return template.HTML(str)
},
})
r.Static("/css", "./templates/css")
r.LoadHTMLGlob("templates/**/*")
r.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "<a href='http://www.baidu.com'>hello template</a>",
})
})
r.GET("/user", func(c *gin.Context) {
c.HTML(http.StatusOK, "user.tmpl", gin.H{
"title": "<a href='http://www.baidu.com'>hello template</a>",
})
})
r.Run(":8081")
}
模版取消转义
go
package main
import (
"github.com/gin-gonic/gin"
"html/template"
"net/http"
)
func main() {
r := gin.Default()
//r.LoadHTMLFiles("./templates/index.tmpl", "./templates/user.tmpl")
r.SetFuncMap(template.FuncMap{
"safe": func(str string) template.HTML {
return template.HTML(str)
},
})
r.LoadHTMLGlob("templates/**/*")
r.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "<a href='http://www.baidu.com'>hello template</a>",
})
})
r.GET("/user", func(c *gin.Context) {
c.HTML(http.StatusOK, "user.tmpl", gin.H{
"title": "<a href='http://www.baidu.com'>hello template</a>",
})
})
r.Run(":8081")
}
go重定向
go
func main() {
//创建路由
r := gin.Default()
r.GET("/index", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")
})
r.Run(":8080")
}
cookie
设置cookie
go
c.SetCookie("site_cookie", "123456", 60*60*24, "/", "", false, false)
删除cookie
go
c.SetCookie("site_cookie", "123456", -1, "/", "", false, false)
读取cookie
go
data, err := c.Cookie("site_cookie")
if err != nil {
log.Println(err)
c.JSON(200, err.Error())
return
}
c.JSON(200, data)
多session
go
func main() {
r := gin.Default()
store := cookie.NewStore([]byte("secret"))
sessionNames := []string{"a", "b"}
r.Use(sessions.SessionsMany(sessionNames, store))
r.GET("/hello", func(c *gin.Context) {
sessionA := sessions.DefaultMany(c, "a")
sessionB := sessions.DefaultMany(c, "b")
if sessionA.Get("name") == nil {
sessionA.Set("name", "b")
sessionA.Save()
}
if sessionB.Get("name") == nil {
sessionB.Set("name", "c")
sessionB.Save()
}
})
r.Run(":8081")
}
redis Session固化存储
go
func main() {
r := gin.Default()
store, _ := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
r.Use(sessions.Sessions("mysession", store))
r.GET("/incr", func(c *gin.Context) {
session := sessions.Default(c)
var cnt int
v := session.Get("count")
if v == nil {
cnt = 0
} else {
cnt = v.(int)
cnt++
}
session.Set("count", cnt)
session.Save()
c.JSON(200, gin.H{
"count": cnt,
})
})
r.Run(":8080")
异步执行与同步执行
go
func main() {
//创建路由
r := gin.Default()
//异步
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)
})
r.Run(":8080")
}
中间件
在gin框架中,中间件是指可以拦截http请求-响应生命周期的特殊函数,在请求-响应生命周期中可以注册多个中间件,每个中间件执行不同的功能,一个中间件执行完再轮到下一个中间件执行。
全局中间件
go
func MiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
fmt.Println("中间件开始执行了")
c.Set("request", "中间件")
status := c.Writer.Status()
fmt.Println("中间件执行完毕", status)
t2 := time.Since(t)
fmt.Println("time:", t2)
}
}
func main() {
r := gin.Default()
//注册中间价
r.Use(MiddleWare())
//{}代码规范
{
r.GET("/ce", func(c *gin.Context) {
req, _ := c.Get("request")
fmt.Println("request:", req)
c.JSON(200, gin.H{"request": req})
})
}
r.Run(":8080")
}
局部中间件
go
func MiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
fmt.Println("中间开始执行了")
c.Set("request", "中间剑")
c.Next()
status := c.Writer.Status()
fmt.Println("中间件执行完毕", status)
t2 := time.Since(t)
fmt.Println("time:", t2)
}
}
func main() {
r := gin.Default()
r.Use(MiddleWare())
{
r.GET("/ce", func(c *gin.Context) {
req, _ := c.Get("request")
fmt.Println("request:", req)
c.JSON(200, gin.H{"request": req})
})
}
r.Run(":8080")
}
定义两个路由,计算执行时间
go
func myTime(c *gin.Context) {
start := time.Now()
c.Next()
since := time.Since(start)
fmt.Println("程序用时:", since)
}
func main() {
r := gin.Default()
//注册中间件
r.Use(myTime)
shoppingGroup := r.Group("/shopping")
{
shoppingGroup.GET("/index", shopIndexHandler)
shoppingGroup.GET("/home", shopHomeHandler)
}
r.Run(":8080")
}
func shopIndexHandler(c *gin.Context) {
time.Sleep(5 * time.Second)
}
func shopHomeHandler(c *gin.Context) {
time.Sleep(3 * time.Second)
fmt.Println("how do you do?")
}
cookie的使用
go
func main() {
r := gin.Default()
r.GET("/cookie", func(c *gin.Context) {
cookie, err := c.Cookie("key_code")
if err != nil {
cookie = "ThisIsCookie"
c.SetCookie("key_code", "value_cookie", 60, "/",
"localhost", false, true)
}
fmt.Printf("cookie的值是:%s\n", cookie)
})
r.Run(":8080")
}
Cookie练习
go
func AuthMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
if cookie, err := c.Request.Cookie("username"); err == nil {
if cookie.String() == "123" {
c.Next()
return
}
}
c.JSON(http.StatusUnauthorized, gin.H{"error": "error"})
c.Abort()
return
}
}
func main() {
r := gin.Default()
r.GET("/login", func(c *gin.Context) {
c.SetCookie("abc", "123", 60, "/", "localhost", false, true)
c.String(200, "Login Success!")
})
r.GET("/home", AuthMiddleWare(), func(c *gin.Context) {
c.JSON(200, gin.H{"data": "home"})
})
r.Run(":8080")
}
结构体验证
go
type Person struct {
Age int `form:"age" binding:"required,gt=10"`
Name string `form:"name" binding:"required"`
Birthday time.Time `form:"birthday" time_format:"2006-01-02"` time_utc: "1"
}
func main() {
r := gin.Default()
r.GET("/51mh", func(c *gin.Context) {
var person Person
if err := c.ShouldBind(&person); err != nil {
c.String(500, fmt.Sprint(err))
return
}
c.String(200, fmt.Sprintf("%#v", person))
})
r.Run(":8080")
}
结构体
go
type Login struct {
User string `uri:"user" validate:"checkName"`
Password string `uri:"password"`
}
func checkName(f1 validator.FieldLevel) bool {
if f1.Field().String() != "root" {
return false
}
return true
}
func main() {
r := gin.Default()
validate := validator.New()
r.GET("/:user/:password", func(c *gin.Context) {
var login Login
err := validate.RegisterValidation("checkName", checkName)
if err := c.ShouldBindUri(&login); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err = validate.Struct(login)
if err != nil {
for _, err := range err.(validator.ValidationErrors) {
fmt.Println(err)
}
return
}
fmt.Println("success")
})
r.Run(":8080")
}