0
点赞
收藏
分享

微信扫一扫

golang入门笔记——gin

佃成成成成 2022-04-27 阅读 85
golang

文章目录

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>
举报

相关推荐

0 条评论