其他分享
首页 > 其他分享> > [ 粗略 ] GoGin

[ 粗略 ] GoGin

作者:互联网

1 Gin框架模板渲染

package main

import (
	"github.com/gin-gonic/gin"
	"html/template"
	"net/http"
)

// 静态文件:
// html页面上用到的样式、图片


func main() {
	// 默认路由器
	r := gin.Default()

	// 加载静态文件
    r.Static("/xxx", "./statics")
    
	// r.Static("/assets", "./statics")

	// gin框架中添加自定义函数
	r.SetFuncMap(template.FuncMap{
		"safe" : func(str string) template.HTML{
			return template.HTML(str)
		},
	})
	// 解析模板
	//r.LoadHTMLFiles("templates/index.tmpl")

	// **表示所有文件夹 *表示所有文件
	r.LoadHTMLGlob("templates/**/*")

	r.GET("/posts/index", func(c *gin.Context) {
		// http请求
		// 模板渲染
		c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
			"title" : "posts/index.tmpl",
		})
	})

	r.GET("/users/index", func(c *gin.Context) {
		// http请求
		// 模板渲染
		c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
			"title" : "<a href='https://bing.com'>必应</a>",
		})
	})
    
    //下面是自己找了一个前端模板试了试
	//r.GET("/home", func(c *gin.Context) {
	//	// http请求
	//	// 模板渲染
	//	c.HTML(http.StatusOK, "home.html", nil)
	//})
	// 启动sever
	
    r.Run(":9090")
}

{{/*post\index.tmpl*/}}

{{define  "posts/index.tmpl"}}
    <!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>posts/index</title>
    </head>
    <body>
    {{.title}}
    </body>
    </html>
{{end}}
{{/*users\index.tmpl*/}}

{{define  "users/index.tmpl"}}
    <!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">
        <link rel="stylesheet" href="/xxx/index.css">
        <title>posts/index</title>
    </head>
    <body>
    {{.title | safe}}

    <script src="/xxx/index.js"></script>
    </body>
    </html>
{{end}}

2 Gin框架返回json

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func main()  {
	r := gin.Default()
	r.GET("/json", func(c *gin.Context) {
		方法一:使用map
		//data := map[string]interface{} {
		//	"name" : "飞鞋",
		//	"message" : "hello dota!",
		//	"age" : 15,
		//}

		// 方法二:使用gin.H
		data := gin.H{
			"name": "飞鞋",
			"message": "hello dota!",
			"age" : 15,
		}
		c.JSON(http.StatusOK, data)
	})
	//方法三: 结构体, 可用tag定制操作
	type msg struct {
		// `tag`
		Name string `json:"name"`
		Message string
		Age int
	}
	r.GET("/another", func(c *gin.Context) {
		data := msg {
			Name: "飞鞋",
			Message: "hello dota",
			Age: 15,
		}
		c.JSON(http.StatusOK, data)
	})


	r.Run(":9090")
}

3 Gin框架获取querystring参数

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

// querystring

func main()  {
	r := gin.Default()

	r.GET("/web", func(c *gin.Context) {
		//获取querystring参数
		// 1. 无默认值
		name := c.Query("query")

		// 2. 有默认值
		//name := c.DefaultQuery("query", "somebody")

		// 3. 确认是否返回正确,
		//name, ok := c.GetQuery("query")
		//if !ok {
		//	name = "somebody"
		//}

		// 渲染
		c.JSON(http.StatusOK, gin.H{
			"name" : name,
		})
	})

	r.GET("/web2", func(c *gin.Context) {
		// 获取querystring多个参数
		// 网页上用 & 连接两个key-value请求
		name := c.Query("query")
		age := c.Query("age")
        
		// 渲染
		c.JSON(http.StatusOK, gin.H{
			"name" : name,
			"age" : age,
		})
	})

	r.Run(":9090")
}

4 Gin框架获取form参数

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

// 获取form表单 参数

func main()  {
	r := gin.Default()
	r.LoadHTMLFiles("./login.html", "./index.html")
	r.GET("/login", func(c *gin.Context) {
		c.HTML(http.StatusOK, "login.html", nil)
	})

	r.POST("/login", func(c *gin.Context) {
		// 获取form提交的数据

		 方法一
		//username := c.PostForm("username")
		//password := c.PostForm("password")

		 方法二
		//username := c.DefaultPostForm("username", "somebody")
		//password := c.DefaultPostForm("password", "***")
		//defaultret := c.DefaultPostForm("xxx", "default")

		// 方法三
		username, ok:= c.GetPostForm("username")
		if !ok {
			username = "羊刀"
		}
		password, ok:= c.GetPostForm("password")
		if !ok {
			username = "***"
		}
		c.HTML(http.StatusOK, "index.html", gin.H{
			"Name": username,
			"Password" : password,
			//"Defaultret" : defaultret,

		})
	})
	r.Run(":9090")
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</head>
<body>
<form action="/login" method="post" novalidate autocomplete="off">
    <div>
        <label for="username">username:</label>
        <input type="text" name="username" id="username">
    </div>
    <div>
        <label for="password">password:</label>
        <input type="password" name="password" id="password">
    </div>
    <div>
        <input type="submit" value="登录">
    </div>

</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>
<h1>Hello, {{.Name}}</h1>
<h1>你的密码是, {{.Password}}</h1>
<!--<h1>展示方法二默认返回:{{.Defaultret}}</h1>-->

</body>
</html>

5 Gin框架获取URI参数

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

// 获取URI参数

func main()  {
	r := gin.Default()
	r.GET("/user/:name/:age", func(c *gin.Context) {
		// 获取路径参数
		name := c.Param("name")
		age := c.Param("age")	//返回的是都是string类型
		c.JSON(http.StatusOK, gin.H{
			"name": name,
			"age": age,
		})
	})

	r.GET("/blog/:year/:month", func(c *gin.Context) {
		year := c.Param("year")
		month := c.Param("month")
		c.JSON(http.StatusOK, gin.H{
			"year": year,
			"month": month,
		})
	})
	r.Run(":9090")
}

6 Gin参数绑定

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

// 参数绑定

type UserInfo struct {
	// 起一个标签名 方便用户传参
	Username string `form:"username" json:"usr"`
	Password string `form:"password" json:"pwd"`
}

func main()  {
	r := gin.Default()
	r.LoadHTMLFiles("./index.html")
	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("%#v\n", u)
			c.JSON(http.StatusOK, gin.H{
				"message" : "ok",
			})
		}
	})

	r.GET("/form", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})

    // 用postman发送post请求测试
	r.POST("/json", 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("%#v\n", u)
			c.JSON(http.StatusOK, gin.H{
				"message" : "ok",
			})
		}
	})
	r.Run(":9090")


}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>index</title>
</head>
<body>
<form action="/form" method="post">
    用户名:
    <input type="text" name="username">
    密码:
    <input type="password" name="password">
    <input type="submit" name="提交">
</form>

</body>
</html>

7 Gin文件上传

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"path"
)

// 参数绑定

type UserInfo struct {
	
}

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.StatusBadRequest, gin.H{
				"error": err.Error(),
			})
		} else {
			// 将读到的保存
			dst := path.Join("./", f.Filename)
			c.SaveUploadedFile(f, dst)
			c.JSON(http.StatusOK, gin.H{
				"status":"OK",
			})
		}
	})

	// 多个文件上传
	//r.POST("/upload", func(c *gin.Context) {
	//	f, _ := c.MultipartForm()
	//	files := f.File["file"]
	//	for _, file := range files {
	//		dst := path.Join("./", file.Filename)
	//		c.SaveUploadedFile(file, dst)
	//	}
	//	c.JSON(http.StatusOK, gin.H{
	//		"status":"OK",
	//	})
	//})

	r.Run(":9090")
}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>index</title>
</head>
<body>
<form action="/upload" method="post">
    <input type="file" name="f1">
    <input type="submit" value="上传">
</form>

</body>
</html>

8 Gin请求重定向

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func main()  {
	r := gin.Default()
	// 重定向 bing.com
	r.GET("/index", func(c *gin.Context) {
		c.Redirect(http.StatusMovedPermanently, "http://www.bing.com")
	})

	// 重定向 自己的网页
	r.GET("/a", func(c *gin.Context) {
		// 修改请求的URI参数
		c.Request.URL.Path = "/b"
		r.HandleContext(c)
	})

	r.GET("/b", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"message" : "b",
		})
	})


	r.Run(":9090")
}

9 Gin路由和路由组

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)
func main()  {
	r := gin.Default()
	// Any可以接收任何请求
	r.Any("/index", func(c *gin.Context) {
		switch c.Request.Method {
		case http.MethodGet:
			c.JSON(http.StatusOK, gin.H{"method": "GET"})
		case http.MethodPost:
			c.JSON(http.StatusOK, gin.H{"method": "Post"})
		}
	})

	// 处理用户查不到的路径
	r.NoRoute(func(c *gin.Context) {
		c.JSON(http.StatusNotFound, gin.H{"msg": "no found"})
	})

	// 路由组
    // group 是公用前缀 
    // 路由组可嵌套
	Group := r.Group("/group")
	{
		Group.GET("/a", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"msg": "a"})
		})
		Group.GET("/b", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"msg": "b"})
		})
		Group.GET("/c", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"msg": "c"})
		})
	}

	r.Run(":9090")
}

10 Gin中间件

10.1 单个中间件

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

// 定义中间件,统计处理函数耗时
func m1(c *gin.Context) {
	fmt.Println("m1 in...")
	// 计时
	start := time.Now()
	// 先调用后续的处理函数
	c.Next()
	// c.Abort()	// 阻止条用后续的处理函数
	cost := time.Since(start)
	fmt.Printf("cost: %v\n", cost)
	fmt.Println("m1 out...")

}


func main()  {
	r := gin.Default()
	r.GET("/index", m1, func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"msg": "ok",
		})
	})
	r.Run(":9090")
}

10.2 全局中间件

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

// 定义中间件,统计处理函数耗时
func m1(c *gin.Context) {
	fmt.Println("m1 in...")
	// 计时
	start := time.Now()
	// 先调用后续的处理函数
	c.Next()
	// c.Abort()	// 阻止条用后续的处理函数
	cost := time.Since(start)
	fmt.Printf("cost: %v\n", cost)
	fmt.Println("m1 out...")

}
func m2(c *gin.Context) {
	fmt.Println("m2 in...")
	// 对应输出1
	c.Next()
	
	// 对应输出2
	//c.Abort()
	
	// 对应输出3
	//return
	
	
	fmt.Println("m2 out...")

}


func main()  {
	r := gin.Default()

	// 全局中间件
	// 调用的时候 按洋葱模型
	// 输出可见
	r.Use(m1, m2)

	r.GET("/index", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"msg": "ok",
		})
	})
    
    // 路由组注册中间件
	// 方法1
	group := r.Group("/haha", m1)
	{
		group.GET("/a", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"msg": "groupa"})
		})
	}

	// 方法2
	//group := r.Group("/haha")
	//group.Use(m1)
	//{
	//	group.GET("/a", func(c *gin.Context) {
	//		c.JSON(http.StatusOK, gin.H{"msg": "groupa"})
	//	})
	//}
	r.Run(":9090")
}

输出1:

m1 in…
m2 in…
m2 out…
cost: 300.5µs
m1 out…

输出2:

m1 in…
m2 in…
m2 out…
cost: 0s
m1 out…

输出3:

m1 in…
m2 in…
cost: 381µs
m1 out…

10.3 跨中间件存取值

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

// 定义中间件,统计处理函数耗时
func m1(c *gin.Context) {
	fmt.Println("m1 in...")
	// 计时
	start := time.Now()
	// 先调用后续的处理函数
	c.Next()
	// c.Abort()	// 阻止条用后续的处理函数
	cost := time.Since(start)
	fmt.Printf("cost: %v\n", cost)
	fmt.Println("m1 out...")

}
func m2(c *gin.Context) {
	fmt.Println("m2 in...")
	
    // 跨中间件存取
	c.Set("name", "飞鞋")
	c.Next()
	fmt.Println("m2 out...")
}


func main()  {
	// 默认使用Logger Recovery 两个中间件
	r := gin.Default()

	// 如果不想使用
	//r := gin.New();

	// 全局中间件
	// 调用的时候 按洋葱模型
	// 输出可见
	r.Use(m1, m2)

	r.GET("/index", func(c *gin.Context) {
		// 从上下文取值(跨中间件存取值)
		name, ok := c.Get("name")
		if !ok{
			name = "匿名用户"
		}
		c.JSON(http.StatusOK, gin.H{
			"msg": name,
		})
	})
	r.Run(":9090")
}

标签:index,粗略,http,func,StatusOK,Context,gin,GoGin
来源: https://blog.csdn.net/Formy7/article/details/115720917