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不为空
}