IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> gin框架学习 -> 正文阅读

[开发测试]gin框架学习

下载并安装Gin

下载并安装gin

go get -u github.com/gin-gonic/gin

将gin引入代码中

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

HTML渲染

创建一个存放模板的templates文件夹,然后在内部写入一个index.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>Document</title>
</head>
<body>
    <h1>
        账号是:{{.name}}
    </h1>
    <h1>
        密码是:{{.pwd}}
    </h1>
</body>
</html>

在gin框架中使用LoadHTMLLGlob()或者LoadHTMLFiles()来渲染HTML模板

func main() {
	r := gin.Default()
	r.LoadHTMLGlob("./templates/*") // 渲染模板
	r.GET("/demo",func(c *gin.Context) {
		c.HTML(http.StatusOK,"index.html",gin.H{ // 使用模板
			"name":"admin",
			"pwd":"123456",
		})
	})
	r.Run()
}

获取参数

获取Query参数

通过Query来获取URL中后面所携带的参数。例如/?name=admin&pwd=123456

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		name := c.Query("name") // admin
		pwd := c.Query("pwd") // 123456
		c.JSON(http.StatusOK, gin.H{
			"name": name,
			"pwd":  pwd,
		})
	})
	r.Run()
}

发个get请求到http://localhost:8080/?name=admin&pwd=123456看下效果

获取form参数

<!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>Document</title>
</head>
<body>
<form method="post" action="/">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>
func main() {
	r := gin.Default()
	r.LoadHTMLFiles("./login.html", "./index.html") // 渲染模板页面
	r.GET("/", func(c *gin.Context) {
		c.HTML(http.StatusOK, "login.html", nil)

	})
	r.POST("/", func(c *gin.Context) {
		username := c.PostForm("username") //对应h5表单中的username
		password := c.PostForm("password")
		//fmt.Println(username)
		c.JSON(http.StatusOK, gin.H{
			"name": username,
			"pwd":  password,
		})
	})
	r.Run()
}

直接访问http://localhost:8080/然后提交表单即可

获取path参数

func main() {
	r := gin.Default()
    r.GET("/user/:username", func(c *gin.Context) { // :username对应下一句代码要获取的参数username
		username := c.Param("username")
		c.JSON(http.StatusOK, gin.H{
			"username": username,
		})
	})
	r.Run()
}

访问http://localhost:8080/user/admin

这时,username就是admin

获取json参数

func main() {
	r := gin.Default()
	r.POST("/json", func(c *gin.Context) {
		// 为了方便,忽略了错误处理
		b, _ := c.GetRawData() // 从c.Request.Body读取请求数据
		// 定义map或结构体
		var m map[string]interface{}
		// 反序列化
		_ = json.Unmarshal(b, &m)

		c.JSON(http.StatusOK, m)
	})
	r.Run()
}

请添加图片描述

路由

普通路由

r.GET("/get",func(c *gin.Context){})
r.POST("/post",func(c *gin.Context){})

以及匹配所有请求方法的Any方法

r.Any("/test",func(c *gin.Context){})

还有没有匹配到路由的跳转界面

r.NoRoute(func(c *gin.Context){
    c.HTML(http.StatusNotFound,"templates/404.html",nil)
})

路由组

将相同前缀URL的路由划分为一个路由组

func main() {
	r := gin.Default()
	user := r.Group("/user")
	user.GET("/index", func(c *gin.Context) {})
	user.POST("/login", func(c *gin.Context) {})
	r.Run()
}

以及,可以嵌套

func main() {
	r := gin.Default()
	user := r.Group("/user")
	user.GET("/index", func(c *gin.Context) {})
	user.POST("/login", func(c *gin.Context) {})
	pwd:=user.Group("/pwd")
	pwd.GET("/pwd",func(c *gin.Context) {})
	r.Run()
}

中间件

//定义一个中间键m1统计请求处理函数耗时
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)
}

func index(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"msg": "ok",
	})
}

func main() {
	r := gin.Default()
	r.GET("/", m1, index)
	r.Run()
}

在中间件中使用Goroutine

注意不能使用原始上下文,必须拷贝一份用

func main(){
    r := gin.Default()
    r.GET("/test1", func(c *gin.Context) {
		// 拷贝一份上下文temp
		temp := c.Copy()
		go func() {
			// 用 time.Sleep() 模拟一个长任务。
			time.Sleep(5 * time.Second)

			// 使用的是复制的上下文 "temp"
			log.Println("Done! in path " + temp.Request.URL.Path)
		}()
	})
	r.Run()
}

参数绑定

参数绑定主要使用了函数ShouldBind()

// 用结构体绑定参数
type UserInfo struct{
    Username string `form:"username"`
    Password string `form:"password"`
}

func main(){
    r := gin.Default()
    r.GET("/user",func(c *gin.Context){
        var u UserInfo
        err := c.ShouldBind(&u)
        if err != nil{
            c.JSON(http.StatusBadGateway, gin.H{
                "error":err.Error(),
            })
        }else{
            c.JSON(http.StatusOk, gin.H{
                "message":"ok"
            })
        }
        fmt.Println(u)
    })
    r.Run()
}

ShouldBind会按照以下顺序解析请求中的数据并完成绑定:

  • 如果是GET请求,只使用Form绑定引擎(Query)
  • 如果是POST请求,首先检查content-type是否为JSON或XML,然后再使用Form(form-data)

文件上传

单文件上传

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>上传文件示例</title>
</head>
<body>
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="upload" multiple>
    <input type="submit" value="上传">
</form>
</body>
</html>
func main(){
    r := gin.Default()
    r.POST("/upload",func(c *gin.Context){
        file, err := c.FormFile("upload") // 这里的参数对应html中form表单文件上传input的name
        if err != nil{
            c.JSON(http.StatusInternalServerError, gin.H{
                "message":err.Error(),
            })
            return
        }
        
        log.Println(file.Filename)
        dst := fmt.Sprintf("D:/testFiles/%s",file.Filename)
        // 上传文件到指定目录
        c.SaveUploadedFile(file,dst)
        c.JSON(http.StatusOk,gin.H{
            "message": fmt.Sprintf("'%s' uploaded!",file.Filename),
        })
    })
    r.Run()
}

请添加图片描述

多文件上传

func main(){
    r := gin.Default()
    r.POST("/upload",func(c *gin.Context){
        form, _ := c.MultipartForm() //
        files := form.File["file"]
        
        for index, file := range files{
            log.Println(file.Filename)
            dst := fmt.Sprintf("")
            c.SaveUploadedFile(file,dst)
        }
        c.JSON(200,gin.H{
            "message": "files uploaded! "
        })
    })
    r.Run()
}

重定向

func main() {
	r := gin.Default()
	r.GET("/test", func(c *gin.Context) {
		c.Redirect(http.StatusMovedPermanently, "https://www.baidu.com/")
	})
	r.Run()
}

或路由重定向

func main() {
	r := gin.Default()
	r.GET("/test1", func(c *gin.Context) {
		// 指定重定向的URL
		c.Request.URL.Path = "/test2"
		r.HandleContext(c)
	})
	r.GET("/test2", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"hello": "world"})
	})
	r.Run()
}

cookie

func main() {
	r := gin.Default()
	r.GET("/cookie", func(c *gin.Context) {
		cookie, err := c.Cookie("gin_cookie")
		if err != nil {
			cookie = "NotSet"
			c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
		}
	})
	r.Run()
}

请添加图片描述

绑定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>Document</title>
</head>
<body>
    <form action="/" method="POST">
        <p>Check some colors</p>
        <label for="red">Red</label>
        <input type="checkbox" name="colors[]" value="red" id="red" />
        <label for="green">Green</label>
        <input type="checkbox" name="colors[]" value="green" id="green" />
        <label for="blue">Blue</label>
        <input type="checkbox" name="colors[]" value="blue" id="blue" />
        <input type="submit" />
    </form>
</body>
</html>
type myForm struct {
    Colors []string `form:"colors[]"`
}

func main() {
    r := gin.Default()

    r.LoadHTMLGlob("views/*")
    r.GET("/", indexHandler)
    r.POST("/", formHandler)

    r.Run(":8080")
}

func indexHandler(c *gin.Context) {
    c.HTML(200, "form.html", nil)
}

func formHandler(c *gin.Context) {
    var fakeForm myForm
    c.Bind(&fakeForm)
    c.JSON(200, gin.H{"color": fakeForm.Colors})
}
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:36:23  更:2022-04-27 11:36:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 9:09:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码