运维八一 运维八一
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)

运维八一

运维,运维!
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)
  • Go

    • 前言

    • Go基础知识

    • Go基本语法

    • 实战项目:简单web服务

    • 基本数据类型

    • 内置运算符

    • 分支和循环

    • 函数 function

    • 结构体 struct

    • 方法 method

    • 实战项目:跟踪函数调用链

    • 接口 interface

    • 并发 concurrency

    • 指针

    • 实战项目:实现轻量级线程池

    • 实战项目:实现TCP服务器

    • go常用包

    • Gin框架

      • gin入门
      • gin工作流程
      • gin中间件
      • gin路由
      • gin请求
        • 数据绑定和校验
        • 响应返回
        • 路由分发
        • Cookie和Session
        • gin项目结构
        • GORM入门
        • 一对多关联查询
      • go随记

    • Python

    • Shell

    • Java

    • Vue

    • 前端

    • 编程浅尝
    • Go
    • Gin框架
    lyndon
    2022-06-27
    目录

    gin请求

    # 2. 请求

    # 2.1 获取GET请求

    # URL ? 参数

    例如:http://127.0.0.1:8080/user/search?username=zhangsan&address=bj

    package main
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	//Default返回一个默认的路由引擎
    	r := gin.Default()
    	r.GET("/user/search", func(c *gin.Context) {
    		username := c.DefaultQuery("username", "小王子")
    		//username := c.Query("username")
    		address := c.Query("address")
    		//输出json结果给调用方
    		c.JSON(http.StatusOK, gin.H{
    			"message":  "ok",
    			"username": username,
    			"address":  address,
    		})
    	})
    	r.Run()
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # url 中 path 参数

    可以通过Context的Param方法来获取API参数,localhost:8000/xxx/zhangsan

    package main
    import (
    	"github.com/gin-gonic/gin"
    	"net/http"
    	"strings"
    )
    
    func main() {
    	r := gin.Default()
    	r.GET("/user/:name/*action", func(c *gin.Context) {
    		name := c.Param("name")
    		action := c.Param("action")
    		//截取/
    		action = strings.Trim(action, "/")
    		c.String(http.StatusOK, name+" blog: "+action)
    	})
    	//默认为监听8080端口
    	r.Run(":8000")
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    # 2.2 获取form参数

    main.go

    package main
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	r := gin.Default()
    	r.POST("/form", func(c *gin.Context) {
    		types := c.DefaultPostForm("type", "post")
    		username := c.PostForm("username")
    		password := c.PostForm("userpassword")
    		// c.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s", username, password, types))
    		c.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s", username, password, types))
    	})
    	r.Run()
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    form.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    <form action="http://localhost:8080/form" method="post" action="application/x-www-form-urlencoded">
        用户名:<input type="text" name="username" placeholder="请输入你的用户名">  <br>
        密&nbsp;&nbsp;&nbsp;码:<input type="password" name="userpassword" placeholder="请输入你的密码">  <br>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    img

    # 2.3 获取json参数

    package main
    
    import (
    	"encoding/json"
    	"github.com/gin-gonic/gin"
    	"net/http"
    )
    
    func main() {
    	//Default返回一个默认的路由引擎
    	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()
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    postman测试

    img

    # 2.4 ShouldBind参数绑定

    可以基于请求的 Content-Type 识别请求数据类型并利用反射机制自动提取请求中QueryString 、 form表单 、 JSON 、 XML 等参数到结构体中。

    ShouldBind() 能够基于请求自动提取 JSON 、 form表单 和 QueryString 类型的数据,并把值绑定到指定的结构体对象。

    package main
    import (
    	"fmt"
    	"net/http"
    	"github.com/gin-gonic/gin"
    )
    // Binding from JSON
    type Login struct {
    	Username string `form:"username" json:"username" binding:"required"`
    	Password string `form:"password" json:"password" binding:"required"`
    }
    func LoginHandler(c *gin.Context) {
    	var login Login
    	if err := c.ShouldBind(&login); err != nil {
    		// 如果数据校验不通过直接返回
    		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    	}
    	c.String(http.StatusOK, fmt.Sprintf("姓名:%s -- 密码:%s", login.Username,
    		login.Password))
    }
    func main() {
    	// 1.创建路由
    	r := gin.Default()
    	// 2.绑定路由规则,执行的函数
    	// 基本路由 /login/
    	r.POST("/login/", LoginHandler)
    	// 3.监听端口,默认在8080
    	fmt.Println("运行地址:http://127.0.0.1:8000/login/")
    	r.Run(":8000")
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    postman测试

    image-20220627000911291

    # 2.5 获取单个文件

    multipart/form-data格式用于文件上传,gin文件上传与原生的 net/http 方法类似,不同在于gin把原生的request封装到c.Request中。

    main.go

    package main
    import (
        "github.com/gin-gonic/gin"
    )
    
    func main() {
        r := gin.Default()
        //限制上传最大尺寸
        r.MaxMultipartMemory = 8 << 20
        r.POST("/upload", func(c *gin.Context) {
            file, err := c.FormFile("file")
            if err != nil {
                c.String(500, "上传图片出错")
            }
            // c.JSON(200, gin.H{"message": file.Header.Context})
            c.SaveUploadedFile(file, file.Filename)
            c.String(http.StatusOK, file.Filename)
        })
        r.Run()
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    upload.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
              上传文件:<input type="file" name="file" >
              <input type="submit" value="提交">
        </form>
    </body>
    </html>
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    上传特定文件

    有的用户上传文件需要限制上传文件的类型以及上传文件的大小,但是gin框架暂时没有这些函数(也有可能是我没找到),因此基于原生的函数写法自己写了一个可以限制大小以及文件类型的上传函数

    package main
    import (
        "fmt"
        "log"
        "net/http"
        "github.com/gin-gonic/gin"
    )
    
    func main() {
        r := gin.Default()
        r.POST("/upload", func(c *gin.Context) {
            _, headers, err := c.Request.FormFile("file")
            if err != nil {
                log.Printf("Error when try to get file: %v", err)
            }
            //headers.Size 获取文件大小
            if headers.Size > 1024*1024*2 {
                fmt.Println("文件太大了")
                return
            }
            //headers.Header.Get("Content-Type")获取上传文件的类型
            if headers.Header.Get("Content-Type") != "image/png" {
                fmt.Println("只允许上传png图片")
                return
            }
            c.SaveUploadedFile(headers, "./video/"+headers.Filename)
            c.String(http.StatusOK, headers.Filname)
        })
        r.Run()
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    # 2.6 获取多个文件

    main.go

    package main
    import (
       "github.com/gin-gonic/gin"
       "net/http"
       "fmt"
    )
    
    // gin的helloWorld
    func main() {
       // 1.创建路由
       // 默认使用了2个中间件Logger(), Recovery()
       r := gin.Default()
       // 限制表单上传大小 8MB,默认为32MB
       r.MaxMultipartMemory = 8 << 20
       r.POST("/upload", func(c *gin.Context) {
          form, err := c.MultipartForm()
          if err != nil {
             c.String(http.StatusBadRequest, fmt.Sprintf("get err %s", err.Error()))
          }
          // 获取所有图片
          files := form.File["files"]
          // 遍历所有图片
          for _, file := range files {
             // 逐个存
             if err := c.SaveUploadedFile(file, file.Filename); err != nil {
                c.String(http.StatusBadRequest, fmt.Sprintf("upload err %s", err.Error()))
                return
             }
          }
          c.String(200, fmt.Sprintf("upload ok %d files", len(files)))
       })
       //默认端口号是8080
       r.Run(":8000")
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35

    upload.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <form action="http://localhost:8000/upload" method="post" enctype="multipart/form-data">
              上传文件:<input type="file" name="files" multiple>
              <input type="submit" value="提交">
        </form>
    </body>
    </html>
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    上次更新: 2022/06/27, 00:59:36
    gin路由
    数据绑定和校验

    ← gin路由 数据绑定和校验→

    最近更新
    01
    ctr和crictl显示镜像不一致
    03-13
    02
    alpine镜像集成常用数据库客户端
    03-13
    03
    create-cluster
    02-26
    更多文章>
    Theme by Vdoing | Copyright © 2015-2024 op81.com
    苏ICP备18041258号-2
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式