【Go开源宝藏】Web框架 GIN 专场 (含思维导图) 持续更新_gin开发路线图

给大家的福利

零基础入门

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:

在这里插入图片描述

因篇幅有限,仅展示部分资料

网络安全面试题

绿盟护网行动

还有大家最喜欢的黑客技术

网络安全源码合集+工具包

所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

)

func main() {
r := gin.Default()
r.GET(“/user/:name/:action”, func(c *gin.Context) {
name := c.Param(“name”) // 使用Param可以获取路由URL里面的数据
action := c.Param(“action”)
c.String(http.StatusOK, name+" rush “+action)
})
_ = r.Run(”:8000")
}


* 获取表单参数,一般用于`POST`,`PUT`请求。


Gin提供了`.PostForm`方法获取Form表单的值。



package main

import (
“fmt”
“github.com/gin-gonic/gin”
“net/http”
)

func main() {
r := gin.Default()
r.POST(“/form”, func(c *gin.Context) {
username := c.PostForm(“username”)
password := c.PostForm(“password”)
c.String(http.StatusOK, fmt.Sprintf(“username:%s,password:%s”, username, password))
})
_ = r.Run(“:8000”)
}


### 1.4 文件上传与下载


#### 1.4.1 上传


* 提供了`.FormFile`来获取文件



package main

import (
“github.com/gin-gonic/gin”
)

func main() {
r := gin.Default()
r.POST(“/upload”, func(c *gin.Context) {
file, err := c.FormFile(“file”) // file是参数名称
if err != nil {
c.String(500, “上传图片出错”) //出错就会返回这个
}
c.SaveUploadedFile(file, file.Filename) // 保存文件
c.String(http.StatusOK, file.Filename) // 返回状态码
})
_ = r.Run(“:8000”)
}


#### 1.4.2 下载


### 1.5 路由拆分


我们一般来说,会把这个路由拆分成`URL`和`处理函数`。这样能高效管理我们的框架逻辑。



import (
“github.com/gin-gonic/gin”
“net/http”
)

func helloHandler(c *gin.Context) { // 把处理函数放在这里,可以处理一些复杂的业务
c.JSON(http.StatusOK, gin.H {
“message”: “Hello World!”, // 通过这个 gin.H{} 进行json格式的返回
})
}

// Router 配置路由信息
func Router() *gin.Engine {
r := gin.Default()
r.GET(“/hello”, helloHandler) // 这样这个路由就比较简洁了。
return r
}


## 2. 数据绑定


### 2.1 json数据格式


* 定义接收数据的结构体


`binding:"required"`修饰的字段,是必须有的,没有是会报错的。后面可以跟着限制,`满足限制`才不会报错。



type Product struct {
Name string form:"name" json:"name"
CategoryID int form:"category\_id" json:"category\_id"
Title string form:"title" json:"title" binding:"required,min=2,max=100"
Info string form:"info" json:"info" binding:"max=1000"
ImgPath string form:"img\_path" json:"img\_path"
Price string form:"price" json:"price"
DiscountPrice string form:"discount\_price" json:"discount\_price"
OnSale string form:"on\_sale" json:"on\_sale"
Num string form:"num" json:"num"
}


`gin`框架中提供了一个`ShouldBindJSON`方法,这样就能可以把`json格式`解析到`结构体`中。



func helloHandler(c *gin.Context) { // 把处理函数放在这里,可以处理一些复杂的业务
var data Product
if err := c.ShouldBindJSON(&data); err != nil {
// 进行数据的绑定,这样传过来的数据就会传入这个data当中
// gin.H封装了生成json数据的工具
c.JSON(http.StatusBadRequest, gin.H{“error”: err.Error()}) // 返回错误信息
return
}
c.JSON(http.StatusOK, gin.H{“status”: “200”})
}

// Router 配置路由信息
func Router() *gin.Engine {
r := gin.Default()
r.GET(“/hello”, helloHandler) // 这样这个路由就比较简洁了。
return r
}


### 2.2 form表单数据


同样的我们使用`2.1`中的`Product结构体`,注意一定要在结构体中,用`tags`标志`form`格式


上面的那个Product结构体是用tags标志了form格式和json格式的,所以两个都能用。



func helloHandler(c *gin.Context) { // 把处理函数放在这里,可以处理一些复杂的业务
var data Product
if err := c.Bind(&data); err != nil {
// Bind()默认解析并绑定form格式,这样传过来的数据就会传入这个data当中
c.JSON(http.StatusBadRequest, gin.H{“error”: err.Error()}) // 返回错误信息
return
}
c.JSON(http.StatusOK, gin.H{“status”: “200”})
}


### 2.3 URI



type Product struct {
Name string form:"name" json:"name" uri:"name”
CategoryID int form:"category\_id" json:"category\_id" uri:"category\_id"
Title string form:"title" json:"title" uri:“title binding:"required,min=2,max=100"
Info string form:"info" json:"info" uri:“info binding:"max=1000"
ImgPath string form:"img\_path" json:"img\_path" uri:"img\_path"
Price string form:"price" json:"price" uri:“price
DiscountPrice string form:"discount\_price" json:"discount\_price" uri:"discount\_price"
OnSale string form:"on\_sale" json:"on\_sale" uri:"on\_sale"
Num string form:"num" json:"num" uri:"num"
}


gin中提供了`ShouldBindUri`方法进行绑定



func helloHandler(c *gin.Context) { // 把处理函数放在这里,可以处理一些复杂的业务
var data Product
if err := c.ShouldBindUri(&data); err != nil {
c.JSON(http.StatusBadRequest, gin.H{“error”: err.Error()}) // 返回错误信息
return
}
c.JSON(http.StatusOK, gin.H{“status”: “200”})
}



> 
> 无论是`ShouldBindJSON`还是`Bind`还是`ShouldBindUri`  
>  不过我个人比较喜欢用`c.ShouldBind()`这种,看个人喜欢吧~
> 
> 
> 


## 3. 参数验证


### 3.1 普通情况



type User struct {
Phone string form:"phone" binding:"required,gt=10" //不能为空并且大于10
Name string form:"name" binding:"required"
Birthday time.Time form:"birthday" time\_format:"2006-01-02"
// 满足格式才能接收,减少了if-else的判断
}


### 3.2 自定义情况


使用 `gopkg.in/go-playground/validator.v8` 包


* 在结构体上,绑定这个`NotNullAndAdmin`。



type User struct {
Phone string form:"phone" binding:"required,gt=10" //不能为空并且大于10
Name string form:"name" binding:"NotNullAndAdmin" // 自定义一个验证
Birthday time.Time form:"birthday" time\_format:"2006-01-02"
// 满足格式才能接收,减少了if-else的判断
}


* 编写自定义方法



func nameNotNullAndAdmin(v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if value, ok := field.Interface().(string); ok {
return value != “” && !(“admin” == value)// 字段不能为空,并且不等于 admin
}
return true
}


* 把我们的自定义注册到`validator`中就好了



if v, ok := binding.Validator.Engine().(\*validator.Validate); ok {
	\_ = v.RegisterValidation("NotNullAndAdmin", nameNotNullAndAdmin)  //注册定义的验证方法
}

## 4. 渲染


### 4.1 数据的响应


* Json 前后端主流的交互数据格式,我自己也是经常用这个。



func main() {
r := gin.Default()
r.GET(“/json”,JsonHandler)
_ = r.Run(“:8000”)
}

func JsonHandler(c *gin.Context) {
c.JSON(200, gin.H{“message”: “HelloJson”, “status”: 200})
}


* Struct



func main() {
r := gin.Default()
r.GET(“/struct”, StructHandler)
_ = r.Run(“:8000”)
}

func StructHandler(c *gin.Context) {
var msg struct {
Name string
Message string
Number int
}
msg.Name = “FanOne”
msg.Message = “Golang”
msg.Number = 10001
c.JSON(200, msg)
}


* XML



func main() {
r := gin.Default()
r.GET(“/xml”, XMLHandler)
_ = r.Run(“:8000”)
}

func XMLHandler(c *gin.Context) {
c.XML(200, gin.H{“message”: “HelloXml”})
}


* YAML



func main() {
r := gin.Default()
r.GET(“/yaml”, YAMLHandler)
_ = r.Run(“:8000”)
}

func YAMLHandler(c *gin.Context) {
c.YAML(200, gin.H{“message”: “HelloYaml”})
}


* ProtoBuf 这几年很火的数据格式



func main() {
r := gin.Default()
r.GET(“/protobuf”, ProtoBufHandler)
_ = r.Run(“:8000”)
}

func ProtoBufHandler(c *gin.Context) {
reps := []int64{int64(1), int64(2)}
// 定义数据
label := “label”
// 传protobuf格式数据
data := &protoexample.Test{
Label: &label,
Reps: reps,
}
c.ProtoBuf(200, data)
}


### 4.2 模板渲染



> 
> * gin支持加载HTML模板, 然后根据模板参数进行配置并返回相应的数据,本质上就是字符串替换
> * `LoadHTMLGlob()`方法可以加载模板文件
> * `Static`方法可以加载静态文件
> 
> 
> 


* 加载HTML模板



func main() {
r := gin.Default()
r.LoadHTMLGlob(“tempate/*”) // 加载你的模板文件 就是html文件嗷
r.GET(“/index”, func(c *gin.Context) {
c.HTML(http.StatusOK, “index.html”, gin.H{“msg”: “HelloWorld”, “status”: “200”})
})
r.Run()
}


* 加载Static静态文件



### 给大家的福利


**零基础入门**


对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


![](https://img-blog.csdnimg.cn/img_convert/95608e9062782d28f4f04f821405d99a.png)


同时每个成长路线对应的板块都有配套的视频提供:


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a91b9e8100834e9291cfcf1695d8cd42.png#pic_center)


因篇幅有限,仅展示部分资料

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 30
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值