路由
创建路由
r := gin.Default() 创建带有默认中间件的路由 r :=gin.new() 创建带有没有中间件的路由
请求方式
1 router.GET("/someGet", getting) 2 router.POST("/somePost", posting) 3 router.PUT("/somePut", putting) 4 router.DELETE("/someDelete", deleting) 5 router.PATCH("/somePatch", patching) 6 router.HEAD("/someHead", head) 7 router.OPTIONS("/someOptions", options)
HTTP服务器
router.Run() 默认服务器 router.Run(":8080") 配置端口 -------------------------------- router := gin.Default() http.ListenAndServe(":8080", router) -------------------------------- router := gin.Default() s := &http.Server{ Addr: ":8080", Handler: router, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } s.ListenAndServe() 自定义服务器配置 --------------------------------
带参数的路由
通过Context的Param方法 func main() { router := gin.Default() //路由必须为/user/{参数} 不可以为/user/或/user router.GET("/user/:name", func(c *gin.Context) { name := c.Param("name") //通过Param获取 c.String(http.StatusOK, "Hello %s", name) }) // *参数名称 表示该参数为可选参数, /user/john/ 和 /user/john/send 都可以 // 如果不存在路由 /user/{:name}, 它将会重定向至 /user/john/ router.GET("/user/:name/*action", func(c *gin.Context) { name := c.Param("name") action := c.Param("action") message := name + " is " + action c.String(http.StatusOK, message) }) router.Run(":8080") }
获取get方式路由的参数 func main() { router := gin.Default() //通过已经设置的参数对象获取参数 // 请求响应url的匹配格式: /welcome?firstname=Jane&lastname=Doe router.GET("/welcome", func(c *gin.Context) { firstname := c.DefaultQuery("firstname", "Guest") //设置初始值 lastname := c.Query("lastname") //c.Request.URL.Query().Get("lastname")的简写 c.String(http.StatusOK, "Hello %s %s", firstname, lastname) }) router.Run(":8080") }
获取POST方式路由的参数 func main() { router := gin.Default() router.POST("/form_post", func(c *gin.Context) { message := c.PostForm("message") nick := c.DefaultPostForm("nick", "anonymous")//设置默认值 c.JSON(200, gin.H{ "status": "posted", "message": message, "nick": nick, }) }) router.Run(":8080") }
get和post混合获取 func main() { router := gin.Default() router.POST("/post", func(c *gin.Context) { id := c.Query("id") page := c.DefaultQuery("page", "0") name := c.PostForm("name") message := c.PostForm("message") fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message) }) router.Run(":8080") } 路由形式:/post?id=12&page=1 post参数将不会存在于路由中,而在form或者ajax中说明
当map作为get参数或者post参数时 在Go中数组只能是数字下标,形式类似于C语言,而php中的数组可以是键值对的形式存在,而在此刻 GO语言中 map担任了键值对数组的功能。 func main() { router := gin.Default() router.POST("/post", func(c *gin.Context) { ids := c.QueryMap("ids") names := c.PostFormMap("names") fmt.Printf("ids: %v; names: %v", ids, names) }) router.Run(":8080") }
文件上传
单文件上传 package main import ( "github.com/gin-gonic/gin" "log" "net/http" ) func main() { router := gin.Default() // 为文件上传的默认大小限制为 32 MB // router.MaxMultipartMemory = 8 << 20 // 8 MB router.POST("/upload", func(c *gin.Context) { // 单文件上传 file, _ := c.FormFile("file") log.Println(file.Filename) //可以用file.Filetype限制类型 //将文件上传到指定目录 // c.SaveUploadedFile(file, dst) //关于上传时的重命名我将测试过后再修改 c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename)) }) router.Run(":8080") }
多文件上传 package main import ( "github.com/gin-gonic/gin" "log" "net/http" ) func main() { router := gin.Default() router.POST("/upload", func(c *gin.Context) { // Multipart form form, _ := c.MultipartForm() files := form.File["upload[]"] for _, file := range files { log.Println(file.Filename) } c.String(http.StatusOK, "Uploaded...") }) router.Run(":8080") }
群组路由
func main() { router := gin.Default() // Simple group: v1 v1 := router.Group("/v1") { v1.POST("/login", loginEndpoint) v1.POST("/submit", submitEndpoint) v1.POST("/read", readEndpoint) } // Simple group: v2 v2 := router.Group("/v2") { v2.POST("/login", loginEndpoint) v2.POST("/submit", submitEndpoint) v2.POST("/read", readEndpoint) } router.Run(":8080") }
中间件
中间件是一个很有用的东西,对于用过php框架(例如laravel,tp5)的人很好理解。中间件的功能很多,例如http校验,登录检测等合理的使用中间件可以使控制器更好的完成自己的职责。 r := gin.Default() 创建带有默认中间件的路由 r :=gin.new() 创建带有没有中间件的路由 //使用自定义中间价 func main() { r := gin.New() // 全局中间件 // 即使您使用GIN_MODE = release进行设置,Logger中间件也会将日志写入gin.DefaultWriter。 // 默认情况下,gin.DefaultWriter = os.Stdout r.Use(gin.Logger()) // Recovery middleware recovers from any panics and writes a 500 if there was one. //Recovery 中间件会恢复(recovers) 任何恐慌(panics) 如果存在恐慌,中间件将会写入500 r.Use(gin.Recovery()) //每一个路由你可以加入任意数量的中间件 r.GET("/benchmark", MyBenchLogger(), benchEndpoint) //在群组路由中添加中间件 authorized := r.Group("/") authorized.Use(AuthRequired()) { authorized.POST("/login", loginEndpoint) authorized.POST("/submit", submitEndpoint) authorized.POST("/read", readEndpoint) // 嵌套群组 testing := authorized.Group("testing") testing.GET("/analytics", analyticsEndpoint) } r.Run(":8080") }
日志
func main() { //禁止使用Console Color, 在你将日志写入文件时不需要用到console color gin.DisableConsoleColor() //记录文件 f, _ := os.Create("gin.log") gin.DefaultWriter = io.MultiWriter(f) // 使用以下代码 如果你需要将记录同时写入日志和控制台中 // gin.DefaultWriter = io.MultiWriter(f, os.Stdout) router := gin.Default() router.GET("/ping", func(c *gin.Context) { c.String(200, "pong") }) router.Run(":8080") }
模型绑定及验证
如果要将请求主体绑定到类型中,请使用模型绑定。 我们目前支持JSON,XML和标准表单值的绑定 type Login struct { User string `form:"user" json:"user" xml:"user" binding:"required"` Password string `form:"password" json:"password" xml:"password" binding:"required"` } func main() { router := gin.Default() // 示例 绑定JSON ({"user": "manu", "password": "123"}) router.POST("/loginJSON", func(c *gin.Context) { var json Login if err := c.ShouldBindJSON(&json); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if json.User != "manu" || json.Password != "123" { c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) return } c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) }) // 示例 绑定 XML ( // <?xml version="1.0" encoding="UTF-8"?> // <root> // <user>user</user> // <password>123</user> // </root>) router.POST("/loginXML", func(c *gin.Context) { var xml Login if err := c.ShouldBindXML(&xml); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if xml.User != "manu" || xml.Password != "123" { c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) return } c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) }) //示例 绑定 HTML form (user=manu&password=123) router.POST("/loginForm", func(c *gin.Context) { var form Login // 将根据头请求类型推断使用depending if err := c.ShouldBind(&form); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if form.User != "manu" || form.Password != "123" { c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) return } c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) }) router.Run(":8080") } [更多示例] https://github.com/gin-gonic/gin