文章目录
Gin简介:
Gin是一个golang的微框架,基于httprouter,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点
Gin特征:
1.速度快:基于基数树的路由,内存占用少。没有反射。可预测的API性能。
中间件支持:传入的HTTP请求可以由中间件链和最终操作处理。
2。Crash—free
Gin可以捕获HTTP请求期间发生的panic并恢复它。这样,你的服务器将始终可用。
3.JSON验证
Gin可以解析和验证请求的JSON-例如,检查所需值的存在
4.路由分组
更好地组织您的路线。需要授权与不需要授权,不同的API版本…此外,组可以无限嵌套,而不会奖低性能。
错误管理
5.Gin提供了一种方便的方法来收集HTTP请求期间发生的所有错误。最终,中间件可以将它们写入日志文件、数据库并通过网络发送它们。
6.内置渲染
Gin为JSON、XML和HTML渲染提供了一个易于使用的API
7.可扩展
创建一个新的中间件非常简单,只需查看示例代码即可
gin的安装
go get -u github.com/gin-gonic/gin
简单的gin实例
package main
import "github.com/gin-gonic/gin"
func Hello(c *gin.Context) {
c.String(200, "hello %s", "world")
c.JSON(200, gin.H{ //以json格式输出
"name": "tom",
"age": "20",
}) //200代表请求成功,gin.H是map的一个快捷方式
}
func main() {
e := gin.Default()
e.GET("/hello", Hello)
e.Run()
}
简单的用户登录实现:
package main
//gin实现简单的登录程序
import "github.com/gin-gonic/gin"
func Login(c *gin.Context) {
c.HTML(200, "login.html", nil)
}
func DoLogin(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
c.HTML(200, "welcome.html", gin.H{
"Username": username,
"Password": password,
})
}
func main() {
e := gin.Default()
e.LoadHTMLGlob("views/*") //获取当前路径下的views文件夹下的所以html文件
e.GET("/login", Login)
e.POST("/login", DoLogin) //post请求交给DoLogin处理
e.Run()
}
welcome.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
欢迎,{{.Username}}
{{.Password}}
</body>
</html>
login.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>Login</title>
</head>
<body>
<form action="/login" method="post">
用户名称:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="Login">
</form>
</body>
</html>
Form表单的处理
package main
import "github.com/gin-gonic/gin"
func TestGet(c *gin.Context) {
s := c.Query("username")
pwd := c.DefaultQuery("password", "123") //如果没有输入密码给它一个默认值“123”
c.String(200, "username:%s password:%s", s, pwd)
//http://localhost:8888/testget?username=zyj&password=1234
}
func TestGetParam(c *gin.Context) {
s := c.Param("username")
s2 := c.Param("age")
c.String(200, "Username:%s", s)
c.String(200, "Age:%s", s2)
//http://localhost:8888/hello/zyj/22
}
func GoSearch(c *gin.Context) {
c.HTML(200, "query.html", nil)
}
func Search(c *gin.Context) {
page := c.DefaultQuery("page", "0")
key := c.PostForm("key")
c.String(200, "page:%s,key:%s", page, key)
}
func main() {
e := gin.Default()
e.LoadHTMLGlob("views/*")
e.GET("/testget", TestGet)
e.GET("/hello/:username/:age", TestGetParam)
e.GET("/goSearch", GoSearch)
e.POST("/search", Search)
e.Run(":8888")
}
//post的运用
query.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="/search?page=1" method="post">
请输入查询关键字:<input type="text" name="key"><br>
<input type="submit" value="查询">
</form>
</body>
</html>
绑定Form表单
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
type User struct {
Username string `form:"username"`
Password string `form:"password"`
Hobby []string `form:"hobby"`
Gender string `form:"gender"`
City string `form:"city"`
}
type User2 struct {
Username string `uri:"username"`
Password string `uri:"password""`
}
func Register(c *gin.Context) {
var user User
err := c.ShouldBind(&user) //form绑定数据
if err != nil {
fmt.Println("绑定失败")
}
c.String(200, "User:%s", user)
//http://localhost:8080/testGetBind?username=zyj&password=123
//这种连接也会将其进行绑定
}
func GoRegister(c *gin.Context) {
c.HTML(200, "login.html", nil)
}
func TestGetBind(c *gin.Context) {
var user User2
err := c.ShouldBind(&user) //form绑定数据
if err != nil {
fmt.Println("绑定失败")
}
c.String(200, "User:%s", user)
//http://localhost:8080/testGetBind?username=zyj&password=123
//通过uri绑定
}
func main() {
e := gin.Default()
e.LoadHTMLGlob("views/*")
e.GET("/testFrom", GoRegister)
e.POST("/register", Register)
e.GET("/testGetBind", TestGetBind)
e.Run()
}
login.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>Login</title>
</head>
<body>
<form action="/register" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
爱好:
<input type="checkbox" name="hobby" value="swimming">游泳
<input type="checkbox" name="hobby" value="basketball">篮球
<br>
性别:<input type="radio" name="gender" id="1" value="m">男
<input type="radio" name="gender" id="2" value="f">女
<br>
城市:<select name="city">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<br>
</select>
<input type="submit" value="注册">
</form>
</body>
</html>
boostrap集成
boostrap下载网站
下载完成后将其中的js和css放入到assets中
简单的集成实例
package main
import "github.com/gin-gonic/gin"
func GoStatic(e *gin.Context) {
e.HTML(200, "test_static.html", nil)
}
func main() {
e := gin.Default()
e.Static("/assets", "./assets") //第一个是访问的路径,第二个路径是css、js存放的路径
e.LoadHTMLGlob("views/*")
e.GET("/gostatic", GoStatic)
e.Run()
}
test_static.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="/gin/asset/css/bootstrap.min.css">
<script src="/gin/asset/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn btn-primary">Left</button>
<button type="button" class="btn btn-primary">Middle</button>
<button type="button" class="btn btn-primary">Right</button>
</div>
</div>
</body>
</html>
中间件的使用
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func Testmw(c *gin.Context) {
c.String(200, "hello %s", "world!")
}
func MyMiddeleware1(c *gin.Context) {
fmt.Println("我的第一个中间件")
}
func MyMiddeleware2(c *gin.Context) {
fmt.Println("我的第二个中间件")
}
func main() {
e := gin.Default()
e.Use(MyMiddeleware1, MyMiddeleware2)
e.GET("/testmw", Testmw)
e.Run()
}
简单实例:用户授权访问
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
//模拟一些私人数据
var secrets = gin.H{
"foo": gin.H{"email": "foot@bar.com", "phone": "123433"},
"austin": gin.H{"email": "austin@example.com", "phone": "666"},
"lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
}
func Handler(c *gin.Context) {
//获取用户,它是由BasicAuth中间件设置
user := c.MustGet(gin.AuthUserKey).(string) //获得当前用户,AuthUserKey就是user快捷键
fmt.Println(user)
if secret, ok := secrets[user]; ok {
c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
} else {
c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET:("})
}
}
func main() {
e := gin.Default()
//这些用户数据也可以从数据库查询
//路由使用gin.BasicAuth()中间件
//gin.Accounts是map[string]string的一种快捷方式
e1 := e.Group("/admin", gin.BasicAuth(
gin.Accounts{
"foo": "bar",
"austin": "1234",
"lena": "hello2",
"manu": "4321",
})) //授权登入/admin的用户由以上那些
//http://localhost:8080/admin/secrets
e1.GET("/secrets", Handler)
e.Run()
}
Cookie的使用
package main
import "github.com/gin-gonic/gin"
func Handler(c *gin.Context) {
s, err := c.Cookie("username") //取username的cookie值
if err != nil {
s = "zyj"
c.SetCookie("username", s, 60*60, "/", "localhost", false, true)
//参数分别为name,value,时间,路径,域,https是否可以访问,是否是只有http请求能够访问
}
c.String(200, "测试cookie")
}
func main() {
e := gin.Default()
e.GET("test_cookie", Handler)
e.Run()
}
使用Session
session库的下载
go get github.com/gin-contrib/sessions
session库的使用
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
func Handle(c *gin.Context) {
session := sessions.Default(c)
//获得session值 Get
if session.Get("hello") != "world" {
//设置
session.Set("hello", "world")
//保存
session.Save()
}
c.JSON(200, gin.H{"hello": session.Get("hello")})
}
func main() {
r := gin.Default()
store := cookie.NewStore([]byte("secret")) //创建一个存储cookie的存储器
r.Use(sessions.Sessions("mysession", store)) //注入中间件,mysession是session名称
r.GET("/hello", Handle)
r.Run(":8000")
}
Gin实现restful风格的CRUD
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"strconv"
)
type User struct {
UId int `json:"uid"`
Name string `json:"name"`
Age int `json:"age"`
}
var users = make([]User, 3)
func init() {
u1 := User{1, "tom", 20}
u2 := User{2, "kite", 30}
u3 := User{3, "rose", 40}
users = append(users, u1, u2, u3)
fmt.Println(users)
}
func find(uid int) (*User, int) {
for i, u := range users {
if u.UId == uid {
return &u, i
}
}
return nil, -1
}
func AddUser(c *gin.Context) {
u4 := User{4, "Joe", 50}
users = append(users, u4)
c.JSON(200, users)
}
func DelUser(c *gin.Context) {
uid := c.Param("uid")
id, _ := strconv.Atoi(uid)
_, i := find(id)
users = append(users[:i], users[i+1:]...)
c.JSON(200, users)
}
func UpdateUser(c *gin.Context) {
uid := c.Param("uid")
id, _ := strconv.Atoi(uid)
u, _ := find(id)
u.Name = "修改的Name"
c.JSON(200, u)
}
func FindUser(c *gin.Context) {
uid := c.Param("uid")
id, _ := strconv.Atoi(uid)
u, _ := find(id)
c.JSON(200, u)
}
func main() {
e := gin.Default()
e.GET("/user/:uid", FindUser) //GET获取请求
e.PUT("/user/:uid", UpdateUser) //PUT修改请求
e.DELETE("/user/:uid", DelUser) //DELETE删除请求
e.POST("/user/", AddUser) //POST添加请求
e.Run()
}
Gin路由文组
package main
import (
"github.com/gin-gonic/gin"
)
func F1(c *gin.Context) {}
func F2(c *gin.Context) {}
func F3(c *gin.Context) {}
func F4(c *gin.Context) {}
func F5(c *gin.Context) {}
func F6(c *gin.Context) {}
func main() {
router := gin.Default()
//http://localhost:8080/blog/list
v1 := router.Group("/blog")
{
v1.POST("/list", F1)
v1.POST("/post", F2)
v1.POST("/add", F3)
}
//http://localhost:8080/video/list
v2 := router.Group("/video"){
v2.POST("/list",F4)
v2.POST("/post",F5)
v2.POST("/add",F6)
}
router.Run("8080")
}
输出渲染
package main
import (
"github.com/gin-gonic/gin"
)
func TestJson(e *gin.Context) {
e.JSON(200, gin.H{
"name": "zyj",
"site": "www.baidu.com",
})
}
func TestXMl(e *gin.Context) {
e.XML(200, gin.H{
"name": "lcc",
"site": "www.sougou.com",
})
}
func TestString(e *gin.Context) {
e.String(200, "zyj")
}
func TestHtml(e *gin.Context) {
e.HTML(200, "login.html", nil)
}
func main() {
e := gin.Default()
e.GET("/test_json", TestJson)
e.GET("/test_xml", TestXMl)
e.LoadHTMLGlob("views/*")
e.GET("/test_html", TestHtml)
e.GET("/test_string", TestString)
e.Run()
}
文件上传
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"log"
"net/http"
)
func Upload(c *gin.Context) {
//单文件
file, _ := c.FormFile("file")
log.Println(file.Filename)
//上传文件到项目根目录,使用原文件名
c.SaveUploadedFile(file, file.Filename)
c.String(http.StatusOK, fmt.Sprintf("'%s' upload!", file.Filename))
}
func GoUpload(c *gin.Context) {
c.HTML(200, "put_file.html", nil)
}
func main() {
e := gin.Default()
e.MaxMultipartMemory = 8 << 20 //设置上传文件的最大内存8MB
e.LoadHTMLGlob("views/*")
e.GET("/upload", GoUpload)
e.POST("/upload", Upload)
e.Run()
}
put_file.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
请选择上传文件:<input type="file" name="file"><br>
<input type="submit" value="上传">
</form>
</body>
</html>