学习 Gin 问题总结 2020.12.29

数据绑定与解析

BindXXXShouldBindXXXShouldBindWith区别

  1. BindXXX

    会自动返回信息,输入无效时,在header写入400

  2. ShouldBindXXX

    返回消息,输入无效时,不会在header写入400状态码,这时候可以自定义返回信息,在使用上相对来说更加灵活。

  3. ShouldBindWith

    gin 1.4 之前,重复使用ShouldBind绑定会报错EOF

    gin 1.4 之后官方提供了一个 ShouldBindBodyWith 的方法,可以支持重复绑定,原理就是将body的数据缓存了下来,但是二次取数据的时候还是得用 ShouldBindBodyWith 才行,直接用 ShouldBind 还是会报错的。

    根据方法内参数b的类型去绑定jsonquery,去绑定obj,不返回状态码。

func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
return b.Bind(c.Request, obj)
}

HTML渲染

func main() {
// 1.创建路由
r := gin.Default()
//静态文件,声明模板文件所在的目录,系统自动解析
r.LoadHTMLGlob("static/html/*") ...
}

LoadHTMLGlob(),该方法参数内的目录下,不能有二级目录,存在二级目录将会panic

而且该方法只能在一个实例中对一个目录使用一次(使用过的目录下的子目录同样是为已使用)。

使用两次

//静态文件,声明模板文件所在的目录,系统自动解析
r.LoadHTMLGlob("static/html/*")
r.LoadHTMLGlob("static/html/html2/*")

将会:

panic: read static\html\html2: The handle is invalid.

如果需要解析两个目录下的HTML文件,可在同一目录下创建两个文件夹:

	//静态文件,声明模板文件所在的目录,系统自动解析
r.LoadHTMLGlob("static/html/*")
r.LoadHTMLGlob("static/html2/*")

[GIN-debug] Loaded HTML Templates (4):

- form.html

- login.html

- upload.html

-

[GIN-debug] Loaded HTML Templates (2):

- uploadMore.html

-

此时将会正常解析两个目录下的HTML模板。


还可以使用:

//静态文件,声明模板文件所在的目录,系统自动解析
r.LoadHTMLGlob("static/**/*")

-[GIN-debug] Loaded HTML Templates (5):

  - form.html
- login.html
- upload.html
- uploadMore.html

static目录下的子目录内的所有模板文件都将被解析。

注意:static目录下的模板文件将不会被解析。

重定向

c.Redirect(http.StatusPermanentRedirect,"http://localhost:8080/updateBook")

状态码可选:

http.StatusPermanentRedirect //永久性重定向

http.StatusTemporaryRedirect //临时性重定向

第二个参数为重定向的地址。

异步处理

// Async 异步处理,保存上传文件,开启相应数量的 goroutine
func Async(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
c.String(http.StatusBadRequest,fmt.Sprintf("get err %s",err.Error()))
}
//根据key:‘files’,获取表单中的文件切片
files := form.File["files"]
fileSum := len(files)
fileName := make([]string,fileSum) //控制上传文件同步问题处理
waitG := sync.WaitGroup{}
waitG.Add(fileSum) for index, file := range files {
fileName[index] = file.Filename
//异步处理时,上下文应该复制一个只读副本,不直接使用原始上下文
cc := c.Copy()
go func(c *gin.Context,fileName string,fileUpload *multipart.FileHeader) {
defer waitG.Done()
fmt.Println("正在保存",fileName)
cc.SaveUploadedFile(fileUpload,fileName)
}(cc,fileName[index],file)
}
waitG.Wait()
c.String(http.StatusOK,"%s",strings.Join(fileName,",\n"))
}

初始写法(错误):

	go func() {
defer waitG.Done()
fmt.Println("正在保存",fileName[index])
cc.SaveUploadedFile(file,fileName[index])
}()
}

错误原因总结:

未进行传参,导致只有最后一个文件被上传,通过debug发现,虽然已经做同步处理(使用WaitGroup),但是goroutine内因为延迟求值的原因,导致每次都只是保存最后一个文件。传入参数fileNamefileUpload后,会立即复制参数,不会出现延迟求值的情况,使得保存文件按顺序进行保存。

最新文章

  1. Python自动化之django URL
  2. cookie小析
  3. Sql Server中不常用的表运算符之PIVOT
  4. Hadoop 2.0安装以及不停集群加datanode
  5. sql server 查找包含字符串的对象
  6. 第10章 使用Apache服务部署静态网站
  7. 20个C语言中常用宏定义总结
  8. 黄聪:HtmlAgilityPack,C#实用的HTML解析类 ---- HtmlNode类
  9. Semantic UI 使用回调函数
  10. C++ const && 二叉树合集
  11. WordPress添加评论回复的电子邮件警报通知
  12. vue引入百度地图api组件封装(根据地址定位)
  13. c# 初识WPF
  14. R贡献文件中文
  15. Python面向对象:杂七杂八的知识点
  16. Linux 环境下umount, 报 device is busy 的问题分析与解决方法
  17. neo4j----创建索引
  18. 算法java实现--动态规划--电路布线问题
  19. C#学习笔记(十六):索引器和重载运算符
  20. JQuery给一个元素绑定两次点击事件(第二次点击事件)

热门文章

  1. 测试:DOCX
  2. 跟随杠精的视角一起来了解Redis的主从复制
  3. MIT-6.005软件构建
  4. 我与PHP,ULM和Vue.js不得不说的故事(一个放荡不羁与一个神神秘秘一个似曾相识,从入门到放弃记录第二章)
  5. ChromiumWebBrowser flash不能自动播放问题解决方案
  6. Python【Python基础】
  7. 第15.30节 PyQt编程实战:通过eventFilter监视QScrollArea的widget()的Paint消息画出scrollAreaWidgetContents的范围矩形
  8. PyQt(Python+Qt)学习随笔:QTreeWidgetItem项列图标的访问方法
  9. 第11.24节 Python 中re模块的其他函数
  10. 第11.17节 Python 正则表达式扩展功能:命名组功能及组的反向引用