[ 粗略 ] 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