Gin 入门



一.使用net 包中开发

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func sayHello(w http.ResponseWriter, r *http.Request) {
	b, err := ioutil.ReadFile("./hellow.txt") // 从txt中读取数据
	if err != nil {
		fmt.Println("打开txt文件错误", err)
		return
	}
	_, _ = fmt.Fprintln(w, string(b))
	//	_, _ = fmt.Fprintln(w, "<h1>Hellow,Golang!你好</h1>")
}

func main() {
	http.HandleFunc("/hellow", sayHello)     // 路由地址和对应的函数
	err := http.ListenAndServe(":9090", nil) // 监听的端口
	if err != nil {
		fmt.Println("http server failed ", err)
		return
	}
}

2.使用 gin 写一个简单的应用

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func sayHellow(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"message": "Hello,你好",
	})
}

func main() {
	r := gin.Default() // 返回默认的路由引擎
	// 指定路由
	r.GET("/hellow", sayHellow)
	// 启动服务
	r.Run(":9090")
}

3.简单的例子2

注意,如果要让结构体能在外部可见,那么他就必须为首字母大写。

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/json", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"name":    "小王子",
			"message": "hellow world",
			"age":     18,
		})
	})
	r.Run(":5000")
}


4.获得Http请求中的参数

1.get 取值

func main() {
	r := gin.Default()
	r.GET("/json", func(c *gin.Context) {
		// 获得从路由中传过来的参数
		name, ok := c.GetQuery("name")
		if !ok {
			fmt.Println("获得参数失败")
		}
		c.JSON(http.StatusOK, gin.H{
			"name": name,
		})
	})
	r.Run(":5000")
}

2. post 取值

直接使用结构体进行绑定

type User struct {
	Name string `json:"name"`
	Pass string `json:"pass"`
}

func main() {
	r := gin.Default()
	r.POST("/json", func(c *gin.Context) {
		var userjson User
		if err := c.ShouldBindJSON(&userjson); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"err": err})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"user": userjson,
		})
	})
	r.Run(":5000")
}



二.中间件

1手写一个中间件

// 制造一个中间件
func M(c *gin.Context) {
	fmt.Println("m中间件函数开始执行")
	t1 := time.Now() // 开始的时间
	c.Next() // 继续往下执行
	//c.Abort() // 阻塞掉不然他执行
	t2:=time.Since(t1)
	fmt.Println("这个时间执行的字符串",t2)
	fmt.Printf("%v",t2)
	fmt.Println("执行完毕")
}

func main() {
	r := gin.Default()
	r.GET("test", M,func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"msg": "shop",
		})
	})
	r.Run(":5000")
}

2.全局注册中间件

// 制造一个中间件
func M(c *gin.Context) {
	fmt.Println("m中间件函数开始执行")
	t1 := time.Now() // 开始的时间
	c.Next() // 继续往下执行
	//c.Abort() // 阻塞掉不然他执行
	t2:=time.Since(t1)
	fmt.Println("这个时间执行的字符串",t2)
}

func M2(c *gin.Context){
	fmt.Println("M2中间件开始执行")
	c.Next()
	fmt.Println("M2中间价执行完毕")
}

func main() {
	r := gin.Default()
	r.Use(M,M2) // 全局注册,
	r.GET("test",func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"msg": "shop",
		})
	})
	r.Run(":5000")
}


// 输出
m中间件函数开始执行
M2中间件开始执行
M2中间价执行完毕
这个时间执行的字符串 1.0674ms
1.0674ms执行完毕


3.Abort 函数

// 制造一个中间件
func M(c *gin.Context) {
	fmt.Println("m中间件函数开始执行")
	t1 := time.Now() // 开始的时间
	//c.Next() // 继续往下执行
	c.Abort() // 阻塞掉不然他执行
	t2:=time.Since(t1)
	fmt.Println("这个时间执行的字符串",t2)
}

func M2(c *gin.Context){
	fmt.Println("M2中间件开始执行")
	c.Next()
	fmt.Println("M2中间价执行完毕")
}

func main() {
	r := gin.Default()
	r.Use(M,M2) // 全局注册,
	r.GET("test",func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"msg": "shop",
		})
	})
	r.Run(":5000")
}

// 拦截
m中间件函数开始执行
这个时间执行的字符串 0s

如果再 m 函数中加上 return,那么连后边的语句都不会执行的。不过这样的话,就会报错了。




4. 添加身份验证(使用闭包)

使用闭包传参

func authonMiddle(flag bool) gin.HandlerFunc {
	return func(c *gin.Context) {
		if flag {
			c.Next()
		} else {
			c.Abort()
		}
	}
}

func main() {
	r := gin.Default()
	r.Use(authonMiddle(false))
	r.GET("test", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"msg": "shop",
		})
	})
	r.Run(":5000")
}


5.往中间件里放值

func M1(c *gin.Context) {
	// 在里面加点东西
	c.Set("name", "zhao")
}
func M2(c *gin.Context) {
	// 从中间件里取值
	name, ok := c.Get("name")
	if !ok {
		fmt.Println("取值出错")
	}else{
		fmt.Println("打印name",name)
	}
}

func main() {
	r := gin.Default()
	r.Use(M1,M2)
	r.GET("test", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"msg": "shop",
		})
	})
	r.Run(":5000")
}

// 输出
打印name zhao


三.数据库管理

测试数据库是否连接成功

package main

// 如果使用 mod  这种包管理工具,就不需要执行 go get 类似的命令了。
import (
	"database/sql" //定义好的通用的数据库接口
	_ "github.com/go-sql-driver/mysql"
)

func main() {
	dsn := "root:123456@tcp(192.168.141.136:3306)/dbname"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}
	defer db.Close()
}

模块化开发的时候,要做成全局变量

package main

// 如果使用 mod  这种包管理工具,就不需要执行 go get 类似的命令了。
import (
	"database/sql" //定义好的通用的数据库接口
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"time"
)

var db *sql.DB

func InitMysql() (err error) {
	dsn := "root:123456@tcp(192.168.141.136:3306)/test01"
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		return err
	} else {
		fmt.Println("格式正确") // 实际上只是格式的校验,不会真正的去连接数据库
	}
	err1 := db.Ping() // 真正的链接
	if err1 != nil {
		fmt.Println("连接错误")
		return
	}
	fmt.Println("连接成功")

	// 对连接进行一些设置
	db.SetConnMaxLifetime(time.Second * 10) // 10 secondsz连接时间
	db.SetMaxOpenConns(20)                  // 最大连接数
	db.SetMaxIdleConns(5)                   // 连接池的最小保留数

	return err
}

func main() {
	err := InitMysql() //模块化开发的时候,要注意将初始化函数给确定了
	if err != nil {
		panic(err)
	}
	defer db.Close() // 注意要在检测报错以后,再关闭,必须确保db不为空
}
posted @ 2021-04-22 02:37  沧海一声笑rush  阅读(210)  评论(0编辑  收藏  举报