Go第七章:Gin框架学习
项目建立须知
通过Goland建立gin项目,将Envrionment设置成如下
GOPROXY=https://goproxy.cn,direct
执行以下指令拉取Gin代码
go get -u github.com/gin-gonic/gin
接口响应
字符串、Json、xml、html、yaml、单文件、文件目录响应
func _string(c *gin.Context) { c.String(http.StatusOK, "你好啊") } func _json(c *gin.Context) { // json响应结构体 type UserInfo struct { UserName string `json:"user_name"` Age int `json:"age"` Password string `json:"-"` //忽略转换为json } //user := UserInfo{"哈哈", 23, "123456"} // c.JSON(200, user)
// json响应map userMap := map[string]string{ "user_name": "122", "age": "12", } c.JSON(200, userMap) } func _xml(c *gin.Context) { c.XML(200, gin.H{"user": "harry", "message": "121", "status": http.StatusOK}) } func _yaml(c *gin.Context) { c.YAML(200, gin.H{"user": "harry", "message": "121", "status": http.StatusOK}) } func _html(c *gin.Context) { c.HTML(200, "index.html", gin.H{"userName": "ddd"}) } func main() { // 创建一个默认的路由 router := gin.Default() // 加载template下的所有模板文件,如index.html router.LoadHTMLGlob("template/*") // 在go中,没有相对文件的路径,它只有相对项目的路径 // 单文件响应 router.StaticFile("/static/1", "./static/1.jpeg") // 文件目录响应 router.StaticFS("/pwd", http.Dir("./static")) // 绑定路由规则和路由函数,访问/index的路由,将有对应的函数去处理 router.GET("/index", _string) router.GET("/json", _json) router.GET("/xml", _xml) router.GET("/yaml", _yaml) router.GET("/html", _html) // 启动监听,gin会把服务启动到本地的0.0.0.0:8080端口上 router.Run("0.0.0.0:8080") }
文件上传
单文件处理
func _upload(c *gin.Context) { file, _ := c.FormFile("file") c.SaveUploadedFile(file, "./uploads/1.txt") c.JSON(200, gin.H{}) }
多文件处理
func _uploads(c *gin.Context) { form, _ := c.MultipartForm() files := form.File["file[]"] for _, file := range files { c.SaveUploadedFile(file, "./uploads/"+file.Filename) } c.JSON(200, gin.H{"msg": fmt.Sprintf("成功上传 %d 个文件", len(files))}) } router.POST("/uploads", _uploads)
文件下载
func _download(c *gin.Context) { c.Header("Content-Type", "application/octet-stream") c.Header("Content-Disposition", "attachment; filename="+"1.txt") c.File("./uploads/1.txt") } router.GET("/download", _download)
重定向
301 Moved Permanently
被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
302 Found
请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
func _redirect(c *gin.Context) { //c.Redirect(301, "https://www.baidu.com") c.Redirect(302, "https://www.baidu.com") } router.GET("/baidu", _redirect)
查询参数query
func _query(c *gin.Context) { //http://localhost:8080/query?user=aaa fmt.Println(c.GetQuery("user")) fmt.Println(c.Query("user")) //http://localhost:8080/query?user=aaa&user=bbb fmt.Println(c.QueryArray("user")) } router.GET("/query", _query)
动态参数
func _param(c *gin.Context) { //http://localhost:8080/param/1 fmt.Println(c.Param("user_id")) } router.GET("/param/:user_id", _param)
表单参数
//可以接收 multipart/form-data;和 application/x-www-form-urlencoded func _form(c *gin.Context) { fmt.Println(c.PostForm("user_id")) fmt.Println(c.DefaultPostForm("user_id", "333")) // 默认值 forms, err := c.MultipartForm() //接收所有的form参数,包括文件 fmt.Println(forms, err) } router.POST("/form", _form)
原始参数
func _raw(c *gin.Context) { body, _ := c.GetRawData() contentType := c.GetHeader("Content-Type") fmt.Println(contentType) } router.POST("/raw", _raw)
请求方式
参数绑定
func _bind(c *gin.Context) { var userInfo UserInfo err := c.ShouldBindJSON(&userInfo) if err != nil { c.JSON(200, gin.H{"msg": err.Error()}) return } c.JSON(200, gin.H{}) } router.POST("/bind", _bind)
bind绑定器
type UserInfo struct { Name string `json:"name" binding:"required"` Age int `json:"age"` Sex string `json:"sex"` }
请求头
设置响应头
路由中间件
单独注册中间件
// m1即为/index的单独中间件 func _m1(c *gin.Context) { fmt.Println("m1") } router.GET("/index", _m1, _string)
放置2个中间件
func _m1(c *gin.Context) { fmt.Println("m1") } func _m2(c *gin.Context) { fmt.Println("m2") } router.GET("/index", _m1, _string, _m2)
全局中间件及其传递数据
func _m4(c *gin.Context) { fmt.Println("m4") c.Set("name", "aaa") } func _m5(c *gin.Context) { fmt.Println("m5") fmt.Println(c.Get("name")) } router.Use(_m4, _m5)