• go gin ShouldBind 绑定参数到结构体struct 数据校验


    数据校验部分参考https://juejin.cn/post/6863765115456454664#heading-7,没有使用 github.com/go-playground/validator/v10,进行更复杂的校验时可以使用

    ShouldBind 可以i绑定各种请求的参数到对应的结构体上

    • 结构体的field必须大写字母开头,否则该field无法绑定
    • form:“age” 表示请求的参数的key是age,比如此时/b1/age=1可以绑定到user.Age,/b1/Age=1不可以绑定
    • json:“age” 表示把u以json返回时,Age的key是age
    • binding:“required” 表示此字段绑定失败会提示错误。不终止程序,其他字段能继续绑定
    • min/max:字符串的最小/大位数
    • lte/gte/lt/gt: 小于等于/大于等于/小于/大于
    • email:需要email格式
    • eqfield=AnotherFiled:本字段的值需要等于AnotherFiled字段的值
    • oneof=m f:需要是m或者f中的一个

    文件上传

    • MultipartForm处理多个或者单个文件,FormFile单个文件,推荐MultipartForm
    • MultipartForm的返回值是*multipart.Form,此结构体有两个field,分别是Value map[string][]string和File map[string][]*FileHeader
    • 代码里,key是html文件里file的name属性,file_是[]*FileHeader(FileHeader切片),所以取得文件要用file_[0]
    • fmt.Sprintf用来拼接字符串,类似python的"xxx{}xx".format
    • path.Ext获取文件后缀名

    前端传多个文件,且不同文件对应不同的name,可以用这个代码。
    如果多个文件用同一个name以数组的形式传递,只能获取第一个文件。此时代码参考https://blog.csdn.net/weixin_43292547/article/details/126933263

    package main
    
    import (
    	"fmt"
    	"html/template"
    	"log"
    	"mime/multipart"
    	"net/http"
    	"path"
    	"time"
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	mainGin()
    }
    
    func mainGin() {
    	r := gin.Default()
    	
    	//据说可以限制文件大小,不起作用
    	// r.MaxMultipartMemory=1 << 20   //1*(2^10)*(2^10)=1m
    	r.MaxMultipartMemory= 1
    	
    	r.Any("/b2", func(c *gin.Context) {
    		c.HTML(http.StatusOK, "upload.html", nil)
    	})
    	
    	r.Any("/b1", func(c *gin.Context) {
    		type user struct {
    			Name   string `binding:"required,min=2,max=4"`
    			Age    int8   `form:"age" json:"age" binding:"required,gte=1,lte=9"`
    			Weight float32
    			Email  string `binding:"required,email"`
    			Email2 string `binding:"required,eqfield=Email"`
    			Gender string `binding:"required,oneof=m f"`
    		}
    		var (
    			u   user
    			f   *multipart.Form
    			err error
    		)
    		if err = c.ShouldBind(&u); err != nil {
    			goto End
    		} else {
    			log.Println(u)
    		}
    
    		// 上传多个文件或单个文件
    		f, err = c.MultipartForm()
    		//fmt.Printf("\nf:%v", f)
    		if err != nil {
    			goto End
    		} else {
    			files:=f.File
    			//fmt.Printf("\nfiles:%v", files)
    			//这里key是html文件里file的name属性,file_是[]*FileHeader(FileHeader切片)
    			for key, file_ := range files{
    				f:=file_[0]
    				//fmt.Printf("\n key:%s:%s", key,f.Filename)
    				//path.Ext获取文件后缀名
    				dest := fmt.Sprintf("./upload/%d-%s%s",  time.Now().Unix(),key,path.Ext(f.Filename))
    				//fmt.Println(dest)
    				if err = c.SaveUploadedFile(f, dest); err != nil {
    					goto End
    				}
    			}
    		}
    
    		// 上传单个文件
    		// f, err = c.FormFile("file1")
    		// if err != nil {
    		// 	goto End
    		// } else {
    		// 	dest := path.Join("./upload", f.Filename)
    		// 	fmt.Println(dest)
    		// 	if err = c.SaveUploadedFile(f, dest); err != nil {
    		// 		goto End
    		// 	}
    		// }
    	End:
    		if err != nil {
    			c.JSON(http.StatusOK, gin.H{"err": err.Error()})
    		} else {
    			c.JSON(http.StatusOK, u)
    		}
    
    	})
    
    • 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
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    //template\upload.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>Documenttitle>
    head>
    <body>
        <form method='post' action='b1' enctype='multipart/form-data'>
            <input name="Name" value="aa"/><br/>
            <input name="age" value="3"/><br/>
            <input name="Weight" value="2.3"/><br/>
            <input name="Email" value="1@a.c"/><br/>
            <input name="Email2" value="1@a.c"/><br/>
            <input name="Gender" value="m"/><br/>
            <input name="file1" type="file"/><br/>
            <input name="file2" type="file"/><br/>
            <button type="submit">submitbutton><br/>
        form>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    redis的一些操作
    数据结构--单链表操作
    字符串函数与内存函数讲解
    【LeetCode 热题 HOT 100】1、两数之和
    一文读懂 HTTP/2 特性
    dig 简明教程
    使用WildCard充值ChatGPT Plus 会员
    理论问题与工程问题的差异在哪里?
    用输出倒逼输入
    xshell和linux什么关系,其实很简单
  • 原文地址:https://blog.csdn.net/weixin_43292547/article/details/126904503