一、基本路由

import ( “net/http”

  1. "github.com/gin-gonic/gin"

)

func main() { r := gin.Default() r.GET(“/“, func(c *gin.Context) { c.String(http.StatusOK, “hello word”) }) r.POST(“/xxxpost”,getting) r.PUT(“/xxxput”) //监听端口默认为8080 r.Run(“:8000”) }

  1. <a name="pbC2Q"></a>
  2. # 二、Restful风格的API
  3. - gin支持Restful风格的API
  4. - 即Representational State Transfer的缩写。直接翻译的意思是”表现层状态转化”,是一种互联网应用程序的API设计理念:URL定位资源,用HTTP描述操作
  5. 1.获取文章 /blog/getXxx Get blog/Xxx<br />2.添加 /blog/addXxx POST blog/Xxx<br />3.修改 /blog/updateXxx PUT blog/Xxx<br />4.删除 /blog/delXxxx DELETE blog/Xxx
  6. <a name="veuFC"></a>
  7. ## Restful风格
  8. Restful是一种设计风格。对于我们Web开发人员来说。就是使用一个url地址表示一个唯一的资源。然后把原来的请求参数加入到请求资源地址中。然后原来请求的增,删,改,查操作。改为使用HTTP协议中请求方式GET、POST、PUT、DELETE表示。<br />把请求参数加入到请求的资源地址中<br />原来的增,删,改,查。使用HTTP请求方式,POST、DELETE、PUT、GET分别一一对应。<br />如何学习restful风格,这里需要明确两点:<br />1、就是把传统的请求参数加入到请求地址是什么样子?<br />传统的方式是:<br />比如:http://ip:port/工程名/资源名?请求参数<br />举例:[http://127.0.0.1:8080/springmvc/book?action=delete&id=1](http://127.0.0.1:8080/springmvc/book?action=delete&id=1)<br />restful风格是:<br />比如:http://ip:port/工程名/资源名/请求参数/请求参数<br />举例:[http://127.0.0.1:8080/springmvc/book/1](http://127.0.0.1:8080/springmvc/book/1)<br />请求的动作删除由请求方式delete决定
  9. <a name="IuPn3"></a>
  10. # 三、API参数
  11. - 可以通过Context的Param方法来获取API参数
  12. - localhost:8000/xxx/zhangsan
  13. ```go
  14. package main
  15. import (
  16. "net/http"
  17. "strings"
  18. "github.com/gin-gonic/gin"
  19. )
  20. func main() {
  21. r := gin.Default()
  22. r.GET("/:name/*action", func(c *gin.Context) {
  23. name := c.Param("name")
  24. action := c.Param("action")
  25. //截取/
  26. action = strings.Trim(action, "/")
  27. c.String(http.StatusOK, name+" is "+action)
  28. })
  29. //默认为监听8080端口
  30. r.Run(":8000")
  31. }

image.png

四、URL参数

  • URL参数可以通过DefaultQuery()或Query()方法获取
  • DefaultQuery()若参数不村则,返回默认值,Query()若不存在,返回空串
  • API ? name=zs ```go package main

import ( “fmt” “net/http”

  1. "github.com/gin-gonic/gin"

)

func main() { r := gin.Default() r.GET(“/user”, func(c *gin.Context) { //指定默认值 //http://localhost:8080/user 才会打印出来默认的值 name := c.DefaultQuery(“name”, “钟强”) c.String(http.StatusOK, fmt.Sprintf(“hello %s”, name)) }) r.Run() }

  1. 不加参数<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21940000/1655189492375-b24e12b6-c152-40cd-afa6-75fd9d09bf79.png#clientId=u7d086936-86f5-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=131&id=u9816135e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=131&originWidth=316&originalType=binary&ratio=1&rotation=0&showTitle=false&size=5879&status=done&style=none&taskId=u671d9514-cac4-4b20-82ac-266cb0eb11e&title=&width=316)<br />加传递参数<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21940000/1655189532835-09be6af1-6693-4121-b7ec-486c943ae626.png#clientId=u7d086936-86f5-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=132&id=u8074be59&margin=%5Bobject%20Object%5D&name=image.png&originHeight=132&originWidth=388&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7018&status=done&style=none&taskId=uacc42cde-49ed-44e2-88f0-2e7407d7eed&title=&width=388)
  2. <a name="fObEU"></a>
  3. # 五、表单参数
  4. - 表单传输为post请求,http常见的传输格式为四种:
  5. - application/json
  6. - application/x-www-form-urlencoded
  7. - application/xml
  8. - multipart/form-data
  9. - 表单参数可以通过PostForm()方法获取,该方法默认解析的是x-www-form-urlencodedfrom-data格式的参数
  10. ```html
  11. <!DOCTYPE html>
  12. <html lang="en">
  13. <head>
  14. <meta charset="UTF-8">
  15. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  16. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  17. <title>Document</title>
  18. </head>
  19. <body>
  20. <form action="http://localhost:8080/form" method="post" action="application/x-www-form-urlencoded">
  21. 用户名:<input type="text" name="username" placeholder="请输入你的用户名"> <br>
  22. 密&nbsp;&nbsp;&nbsp;码:<input type="password" name="userpassword" placeholder="请输入你的密码"> <br>
  23. <input type="submit" value="提交">
  24. </form>
  25. </body>
  26. </html>
  1. package main
  2. //
  3. import (
  4. "fmt"
  5. "net/http"
  6. "github.com/gin-gonic/gin"
  7. )
  8. func main() {
  9. r := gin.Default()
  10. r.POST("/form", func(c *gin.Context) {
  11. types := c.DefaultPostForm("type", "post")
  12. username := c.PostForm("username")
  13. password := c.PostForm("userpassword")
  14. // c.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s", username, password, types))
  15. c.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s", username, password, types))
  16. })
  17. r.Run()
  18. }

image.png
image.png

六、上传单个文件

  • multipart/form-data格式用于文件上传
  • gin文件上传与原生的net/http方法类似,不同在于gin把原生的request封装到c.Request中
    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
    7. <title>Document</title>
    8. </head>
    9. <body>
    10. <form action="http://localhost:8000/upload" method="post" enctype="multipart/form-data">
    11. 上传文件:<input type="file" name="file" >
    12. <input type="submit" value="提交">
    13. </form>
    14. </body>
    15. </html>
    ```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. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/21940000/1655190082179-0e112648-1b28-402d-b40c-27820e7c8db6.png#clientId=u7d086936-86f5-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=172&id=u93776faf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=172&originWidth=641&originalType=binary&ratio=1&rotation=0&showTitle=false&size=15200&status=done&style=none&taskId=u6eb80dec-56cb-4ef2-ac5c-08e786b3417&title=&width=641)
  2. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/21940000/1655190069111-c270959b-7628-451c-8746-dfa65f4b740f.png#clientId=u7d086936-86f5-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=169&id=ucf396fc9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=169&originWidth=447&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8096&status=done&style=none&taskId=u50327af2-1170-42b5-a35b-588ff68d778&title=&width=447)
  3. <a name="gO6V3"></a>
  4. ## 上传特定文件
  5. 有的用户上传文件需要限制上传文件的类型以及上传文件的大小,但是gin框架暂时没有这些函数(也有可能是我没找到),因此基于原生的函数写法自己写了一个可以限制大小以及文件类型的上传函数
  6. ```go
  7. package main
  8. import (
  9. "fmt"
  10. "log"
  11. "net/http"
  12. "github.com/gin-gonic/gin"
  13. )
  14. func main() {
  15. r := gin.Default()
  16. r.POST("/upload", func(c *gin.Context) {
  17. _, headers, err := c.Request.FormFile("file")
  18. if err != nil {
  19. log.Printf("Error when try to get file: %v", err)
  20. }
  21. //headers.Size 获取文件大小
  22. if headers.Size > 1024*1024*2 {
  23. fmt.Println("文件太大了")
  24. return
  25. }
  26. //headers.Header.Get("Content-Type")获取上传文件的类型
  27. if headers.Header.Get("Content-Type") != "image/png" {
  28. fmt.Println("只允许上传png图片")
  29. return
  30. }
  31. c.SaveUploadedFile(headers, "./video/"+headers.Filename)
  32. c.String(http.StatusOK, headers.Filename)
  33. })
  34. r.Run(":8000")
  35. }

七、上传多个文件

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <form action="http://localhost:8000/upload" method="post" enctype="multipart/form-data">
  11. 上传文件:<input type="file" name="files" multiple>
  12. <input type="submit" value="提交">
  13. </form>
  14. </body>
  15. </html>
  1. package main
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "net/http"
  5. "fmt"
  6. )
  7. // gin的helloWorld
  8. func main() {
  9. // 1.创建路由
  10. // 默认使用了2个中间件Logger(), Recovery()
  11. r := gin.Default()
  12. // 限制表单上传大小 8MB,默认为32MB
  13. r.MaxMultipartMemory = 8 << 20
  14. r.POST("/upload", func(c *gin.Context) {
  15. form, err := c.MultipartForm()
  16. if err != nil {
  17. c.String(http.StatusBadRequest, fmt.Sprintf("get err %s", err.Error()))
  18. }
  19. // 获取所有图片
  20. files := form.File["files"]
  21. // 遍历所有图片
  22. for _, file := range files {
  23. // 逐个存
  24. if err := c.SaveUploadedFile(file, file.Filename); err != nil {
  25. c.String(http.StatusBadRequest, fmt.Sprintf("upload err %s", err.Error()))
  26. return
  27. }
  28. }
  29. c.String(200, fmt.Sprintf("upload ok %d files", len(files)))
  30. })
  31. //默认端口号是8080
  32. r.Run(":8000")
  33. }

m_412e71f16e1d48a9862eb48f9f8a7617_r.pngm_d700ea7d7f803286c121b9e646111dde_r.png

八、routes group

  • routes group是为了管理一些相同的URL ```go package main

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

// gin的helloWorld

func main() { // 1.创建路由 // 默认使用了2个中间件Logger(), Recovery() r := gin.Default() // 路由组1 ,处理GET请求 v1 := r.Group(“/v1”) // {} 是书写规范 { v1.GET(“/login”, login) v1.GET(“submit”, submit) } v2 := r.Group(“/v2”) { v2.POST(“/login”, login) v2.POST(“/submit”, submit) } r.Run(“:8000”) }

func login(c *gin.Context) { name := c.DefaultQuery(“name”, “jack”) c.String(200, fmt.Sprintf(“hello %s\n”, name)) }

func submit(c *gin.Context) { name := c.DefaultQuery(“name”, “lily”) c.String(200, fmt.Sprintf(“hello %s\n”, name)) }

![image.png](https://cdn.nlark.com/yuque/0/2022/png/21940000/1655190695854-1895986a-d20c-4eca-bed0-b158f63cae42.png#clientId=u7d086936-86f5-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=126&id=ua7c967f5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=126&originWidth=427&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8155&status=done&style=none&taskId=u9fbcaa97-18d4-4157-b551-0e7d51f4f24&title=&width=427)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/21940000/1655191117294-a2cbd26b-c212-4334-91f3-c2eca845b7b3.png#clientId=u7d086936-86f5-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=109&id=u0984bb80&margin=%5Bobject%20Object%5D&name=image.png&originHeight=109&originWidth=613&originalType=binary&ratio=1&rotation=0&showTitle=false&size=4582&status=done&style=none&taskId=u187f31e3-4737-45cd-9613-397310e4893&title=&width=613)
<a name="yNK3r"></a>
# 九、gin框架实现404页面
```go
package main

import (
    "fmt"
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/user", func(c *gin.Context) {
        //指定默认值
        //http://localhost:8080/user 才会打印出来默认的值
        name := c.DefaultQuery("name", "钟强")
        c.String(http.StatusOK, fmt.Sprintf("hello %s", name))
    })
    r.NoRoute(func(c *gin.Context) {
        c.String(http.StatusNotFound, "404 not found2222")
    })
    r.Run()
}

image.png

十、路由原理

  • httprouter会将所有路由规则构造一颗前缀树
  • 例如有 root and as at cn com

m_ea7725e3aaf4bfa1bafa369421c71c6f_r.jpg