失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > github.com/gin-gonic/gin 中间件

github.com/gin-gonic/gin 中间件

时间:2019-07-07 04:18:00

相关推荐

github.com/gin-gonic/gin   中间件

/p/98965b3ff638/

/gin-gonic/gin是一个轻量级的 WEB 框架,支持 RestFull 风格 API,支持 GET,POST,PUT,PATCH,DELETE,OPTIONS 等 http 方法,支持文件上传,分组路由,Multipart/Urlencoded FORM,以及支持 JsonP,参数处理等等功能,这些都和 WEB 紧密相关,通过提供这些功能,使开发人员更方便地处理 WEB 业务。

使用 GET, POST, PUT, PATCH, DELETE, OPTIONS

func main() {// Disable Console Color// gin.DisableConsoleColor()// 使用默认中间件创建一个gin路由器// logger and recovery (crash-free) 中间件router := gin.Default()router.GET("/someGet", getting)router.POST("/somePost", posting)router.PUT("/somePut", putting)router.DELETE("/someDelete", deleting)router.PATCH("/somePatch", patching)router.HEAD("/someHead", head)router.OPTIONS("/someOptions", options)// 默认启动的是 8080端口,也可以自己定义启动端口router.Run()// router.Run(":3000") for a hard coded port}

项目中导入

import "/gin-gonic/gin"

导入NET/HTTP(可选)。例如,如果使用诸如HTTP.StasuCK之类的常数,则需要这样做。

import "net/http"

A demo:

package mainimport "/gin-gonic/gin"func main() {r := gin.Default()r.GET("/ping", func(c *gin.Context) {c.JSON(200,gin.H{"message":"pong",})})r.Run()}

启动后,在浏览器输入:浏览其会渲染输出:

http://127.0.0.1:8080/ping

还可以用如下的方式,渲染浏览器页面输出字符串:

package mainimport ("/gin-gonic/gin""net/http")func main() {router := gin.Default()router.GET("/someGet",getting)router.Run()}func getting(c *gin.Context) {c.String(http.StatusOK,"Hello gin")}

http://127.0.0.1:8080/someGet

我们点开源码发现,不管是渲染输出json格式、还是简单的字符串都是调用了c.Render方法,以下只是列出了2种,还有其他的诸如HTML、IndentedJSON、SecureJSON、JSONP、AsciiJSON、XML、YAML、ProtoBuf等。

func (c *Context) String(code int, format string, values ...interface{}) {c.Render(code, render.String{Format: format, Data: values})}

func (c *Context) JSON(code int, obj interface{}) {c.Render(code, render.JSON{Data: obj})}

获取路径中的参数:

package mainimport ("/gin-gonic/gin""net/http")func main() {router := gin.Default()// 此规则能够匹配/someGet/aaa这种格式,但不能匹配/usomeGet/ 或 /someGet这种格式router.GET("/someGet/:name",getting)// 但是,这个规则既能匹配/someGet/aaa/格式也能匹配/someGet/aaa/send这种格式// 如果没有其他路由器匹配/someGet/aaa,它将重定向到/someGet/aaa/router.GET("/someGet/:name/*action", func(c *gin.Context) {name := c.Param("name")action := c.Param("action")message := name + "is" + actionc.String(http.StatusOK,message)})router.Run()}func getting(c *gin.Context) {name := c.Param("name")c.String(http.StatusOK,"Hello %s",name)}

所以我们浏览器输入http://0.0.0.0:8080/someGet/aaaa可以

http://0.0.0.0:8080/someGet/或者http://0.0.0.0:8080/someGet都报错误

以上是一个参数,我们还可以定义多级参数。

http://127.0.0.1:8080/someGet/bbb

获取Get参数:

package mainimport ("/gin-gonic/gin""net/http")func main() {router := gin.Default()// 匹配的url格式: /someGet?firstname=Jane&lastname=Doerouter.GET("/someGet",getting)router.Run()}func getting(c *gin.Context) {firstname := c.DefaultQuery("firstname","Guest")lastname := c.Query("lastname")c.String(http.StatusOK,"Hello: %s,%s",firstname,lastname)}

浏览器输入http://127.0.0.1:8080/someGet?firstname=wyf&lastname=123

渲染页面输出为Hello wyf 123

浏览器输入http://127.0.0.1:8080/someGet?lastname=123,渲染页面输出为Hello Guest 123

http://127.0.0.1:8080/someGet?firstname=aaa&lastname=bbb

http://127.0.0.1:8080/someGet?lastname=123

获取Post 参数

package mainimport ("/gin-gonic/gin")func main() {router := gin.Default()router.POST("/someGet",getting)router.Run()}func getting(c *gin.Context) {message := c.PostForm("message")nick := c.DefaultPostForm("nick","anonymous") // 此方法可以设置默认值c.JSON(200,gin.H{"status":"posted","message":message,"nick":nick,})}

Get+Post 混合形式:

package mainimport ("/gin-gonic/gin""net/http")func main() {router := gin.Default()router.POST("/someGet",getting)router.Run()}func getting(c *gin.Context) {id := c.Query("id")page := c.DefaultQuery("page","0")name := c.PostForm("name")message := c.PostForm("message")c.String(http.StatusOK,"id: %s; page: %s; name: %s; message: %s",id,page,name,message)}

构造Map格式:

package mainimport ("fmt""/gin-gonic/gin""net/http")func main() {router := gin.Default()router.POST("/someGet",getting)router.Run()}func getting(c *gin.Context) {ids := c.QueryMap("ids")names := c.PostFormMap("names")fmt.Printf("ids:%v; names:%v\n",ids,names)c.JSON(200,gin.H{"ids":ids,"names":names,})c.String(http.StatusOK,"ids:%v; names:%v",ids,names)}

路由分组:

func main() {router := gin.Default()// Simple group: v1v1 := router.Group("/v1"){v1.POST("/login", loginEndpoint)v1.POST("/submit", submitEndpoint)v1.POST("/read", readEndpoint)}// Simple group: v2v2 := router.Group("/v2"){v2.POST("/login", loginEndpoint)v2.POST("/submit", submitEndpoint)v2.POST("/read", readEndpoint)}router.Run(":8080")}

package mainimport ("fmt""/gin-gonic/gin")func main() {router := gin.Default()v1 := router.Group("/v1"){v1.GET("/read",readEndpoint)}v2 := router.Group("/v2"){v2.GET("/login",loginEndpoint)}router.Run(":8080")}func readEndpoint(c *gin.Context) {fmt.Println("read")}func loginEndpoint(c *gin.Context) {fmt.Println("login")}

浏览器输入http://127.0.0.1:8080/v1/read

后台log输出read

浏览器输入http://127.0.0.1:8080/v2/login

后台log输出login

上传文件

上传文件的文件名可以由用户自定义,所以可能包含非法字符串,为了安全起见,应该由服务端统一文件名规则。

单文件上传:

func main() {router := gin.Default()// 给表单限制上传大小 (默认 32 MiB)// router.MaxMultipartMemory = 8 << 20 // 8 MiBrouter.POST("/upload", func(c *gin.Context) {// 单文件file, _ := c.FormFile("file")log.Println(file.Filename)// 上传文件到指定的路径// c.SaveUploadedFile(file, dst)c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))})router.Run(":8080")}

curl 测试:

curl -X POST http://localhost:8080/upload \-F "file=@/Users/appleboy/test.zip" \-H "Content-Type: multipart/form-data"

多文件上传:

func main() {router := gin.Default()// 给表单限制上传大小 (默认 32 MiB)// router.MaxMultipartMemory = 8 << 20 // 8 MiBrouter.POST("/upload", func(c *gin.Context) {// 多文件form, _ := c.MultipartForm()files := form.File["upload[]"]for _, file := range files {log.Println(file.Filename)// 上传文件到指定的路径// c.SaveUploadedFile(file, dst)}c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))})router.Run(":8080")}

curl 测试:

curl -X POST http://localhost:8080/upload \-F "upload[]=@/Users/appleboy/test1.zip" \-F "upload[]=@/Users/appleboy/test2.zip" \-H "Content-Type: multipart/form-data"

中间件使用详解

无中间件启动:

使用r := gin.New()代替r := gin.Default() // 默认启动方式,包含 Logger、Recovery 中间件

使用中间件:

func main() {// 创建一个不包含中间件的路由器r := gin.New()// 全局中间件// 使用 Logger 中间件r.Use(gin.Logger())// 使用 Recovery 中间件r.Use(gin.Recovery())// 路由添加中间件,可以添加任意多个r.GET("/benchmark", MyBenchLogger(), benchEndpoint)// 路由组中添加中间件// authorized := r.Group("/", AuthRequired())// exactly the same as:authorized := r.Group("/")// per group middleware! in this case we use the custom created// AuthRequired() middleware just in the "authorized" group.authorized.Use(AuthRequired()){authorized.POST("/login", loginEndpoint)authorized.POST("/submit", submitEndpoint)authorized.POST("/read", readEndpoint)// nested grouptesting := authorized.Group("testing")testing.GET("/analytics", analyticsEndpoint)}// Listen and serve on 0.0.0.0:8080r.Run(":8080")}

写日志文件:

func main() {// 禁用控制台颜色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")}

自定义日志格式

func main() {router := gin.New()// LoggerWithFormatter 中间件会将日志写入 gin.DefaultWriter// By default gin.DefaultWriter = os.Stdoutrouter.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {// 你的自定义格式return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",param.ClientIP,param.TimeStamp.Format(time.RFC1123),param.Method,param.Path,param.Request.Proto,param.StatusCode,param.Latency,param.Request.UserAgent(),param.ErrorMessage,)}))router.Use(gin.Recovery())router.GET("/ping", func(c *gin.Context) {c.String(200, "pong")})router.Run(":8080")}

输出示例:

::1 - [Fri, 07 Dec 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "

如果觉得《github.com/gin-gonic/gin 中间件》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。