自学内容网 自学内容网

go之web框架gin

介绍

Gin 是一个用 Go (Golang) 编写的 Web 框架。 它具有类似 martini 的 API,性能要好得多,多亏了 httprouter,速度提高了 40 倍。 如果您需要性能和良好的生产力,您一定会喜欢 Gin。

安装

go get -u github.com/gin-gonic/gin

快速开始

package main

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

func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}

接受请求参数

公共部分

package main

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

func main() {
router := gin.Default()
 //调用方法
router.Run(":8080")
}

get请求

获取路径上数据(post一样)

使用gin.Context.Query("参数名")获取

func main() {
router := gin.Default()
testGetUrl(router)
router.Run(":8080")
}
func testGetUrl(router *gin.Engine) {
router.GET("/getUrl", func(c *gin.Context) {
// 获取参数值
name := c.Query("name")
age := c.Query("age")
// 返回响应
c.JSON(http.StatusOK, gin.H{
"name": name,
"age":  age,
})
})
}

获取路由参数(post一样)

package main

import (
"github.com/gin-gonic/gin"
"io"
"net/http"
"net/url"
"os"
)

func main() {
router := gin.Default()
testRouteParams(router)
router.Run(":8080")
}
func testRouteParams(router *gin.Engine) {
router.GET("/routeParams/:name/:age", func(c *gin.Context) {
// 获取参数值
name := c.Param("name")
age := c.Param("age")
// 返回响应
c.JSON(http.StatusOK, gin.H{
"name": name,
"age":  age,
})
})
}

获取cookie(post一样)

package main

import (
"github.com/gin-gonic/gin"
"io"
"net/http"
"net/url"
"os"
)

func main() {
router := gin.Default()
testCookies(router)
router.Run(":8080")
}
func testCookies(router *gin.Engine) {
router.GET("/cookies", func(c *gin.Context) {
// 获取参数值
name, _ := c.Cookie("name")
age, _ := c.Cookie("age")
// 返回响应
c.JSON(http.StatusOK, gin.H{
"name": name,
"age":  age,
})
})
}

 

获取表单参数(post一样)

func main() {
router := gin.Default()
testGetForm(router)
router.Run(":8080")
}
func testGetForm(router *gin.Engine) {
router.GET("/getForm", func(c *gin.Context) {
var form User
// 在这种情况下,将自动选择合适的绑定
if c.ShouldBind(&form) == nil {
// 返回响应
c.JSON(http.StatusOK, gin.H{
"name": form.Name,
"age":  form.Age,
})
}

})
}

获取请求头(post一样)

func main() {
router := gin.Default()
testGetHeader(router)
router.Run(":8080")
}
func testGetHeader(router *gin.Engine) {
router.GET("/getHeader", func(c *gin.Context) {
// 获取参数值
name := c.GetHeader("name")
age := c.GetHeader("age")
contentType := c.GetHeader("Content-Type")
// 返回响应
c.JSON(http.StatusOK, gin.H{
"name":        name,
"age":         age,
"contentType": contentType,
})
})
}

 

post请求

获取请求体数据

和post表单一样 

func main() {
router := gin.Default()
testPostForm(router)
router.Run(":8080")
}
func testPostForm(router *gin.Engine) {
router.POST("/postForm", func(c *gin.Context) {
var form User
// 在这种情况下,将自动选择合适的绑定
if c.ShouldBind(&form) == nil {
// 返回响应
c.JSON(http.StatusOK, gin.H{
"name": form.Name,
"age":  form.Age,
})
}

})
}

 文件上传下载

上传单个文件

package main

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

func main() {
router := gin.Default()
testUpload(router)
router.Run(":8080")
}
func testUpload(router *gin.Engine) {
// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// 单文件
file, _ := c.FormFile("file")
dst := file.Filename
// 上传文件至指定的完整文件路径
c.SaveUploadedFile(file, dst)
// 返回响应
c.JSON(http.StatusOK, gin.H{
"name": file.Filename,
})
})
}

 

上传多个文件

package main

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

func main() {
router := gin.Default()
testUploadMany(router)
router.Run(":8080")
}
func testUploadMany(router *gin.Engine) {
// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/uploadMany", func(c *gin.Context) {
// Multipart form
form, _ := c.MultipartForm()
fileNames := make([]string, 0)
files := form.File["fileList"]
for _, file := range files {
// 上传文件至指定目录
c.SaveUploadedFile(file, "filedir/"+file.Filename)
fileNames = append(fileNames, file.Filename)
}
// 返回响应
c.JSON(http.StatusOK, gin.H{
"name": fileNames,
})
})
}

 

 

下载文件 

package main

import (
"github.com/gin-gonic/gin"
"io"
"net/http"
"net/url"
"os"
)

func main() {
router := gin.Default()
testDownload(router)
router.Run(":8080")
}
func testDownload(router *gin.Engine) {
router.POST("/download", func(c *gin.Context) {
// 获取文件路径
targetFileName := "照片1.png"
filePath := "filedir/" + targetFileName
// 检查文件是否存在
_, err := os.Stat(filePath)
if os.IsNotExist(err) {
c.String(http.StatusNotFound, "File not found")
return
}
//中文名称会乱码,导致下载失败,所以需要编码
name := url.QueryEscape(targetFileName)
// 设置响应头,指定文件名和内容类型
c.Header("Content-Disposition", "attachment; filename="+name)
c.Header("Content-Type", "application/octet-stream")
// 打开文件
file, err := os.Open(filePath)
if err != nil {
c.String(http.StatusInternalServerError, "Error opening file")
return
}
defer file.Close()
// 将文件内容写入响应体
_, err = io.Copy(c.Writer, file)
if err != nil {
c.String(http.StatusInternalServerError, "Error copying file")
return
}
})
}

由于是postman下载的,没法解析为中文,用浏览器下载就没问题了

日志

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.Default()

// 简单的路由组: v1
v1 := router.Group("/v1")
{
v1.POST("/login", loginEndpoint)
v1.POST("/submit", submitEndpoint)
v1.POST("/read", readEndpoint)
}

// 简单的路由组: v2
v2 := router.Group("/v2")
{
v2.POST("/login", loginEndpoint)
v2.POST("/submit", submitEndpoint)
v2.POST("/read", readEndpoint)
}

router.Run(":8080")
}

运行多个服务

package main

import (
"log"
"net/http"
"time"

"github.com/gin-gonic/gin"
"golang.org/x/sync/errgroup"
)

var (
g errgroup.Group
)

func router01() http.Handler {
e := gin.New()
e.Use(gin.Recovery())
e.GET("/", func(c *gin.Context) {
c.JSON(
http.StatusOK,
gin.H{
"code":  http.StatusOK,
"error": "Welcome server 01",
},
)
})

return e
}

func router02() http.Handler {
e := gin.New()
e.Use(gin.Recovery())
e.GET("/", func(c *gin.Context) {
c.JSON(
http.StatusOK,
gin.H{
"code":  http.StatusOK,
"error": "Welcome server 02",
},
)
})

return e
}

func main() {
server01 := &http.Server{
Addr:         ":8080",
Handler:      router01(),
ReadTimeout:  5 * time.Second,
WriteTimeout: 10 * time.Second,
}

server02 := &http.Server{
Addr:         ":8081",
Handler:      router02(),
ReadTimeout:  5 * time.Second,
WriteTimeout: 10 * time.Second,
}

g.Go(func() error {
return server01.ListenAndServe()
})

g.Go(func() error {
return server02.ListenAndServe()
})

if err := g.Wait(); err != nil {
log.Fatal(err)
}
}

重定向

HTTP 重定向很容易。 内部、外部重定向均支持。

r.GET("/test", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
})

通过 POST 方法进行 HTTP 重定向。请参考 issue:#444

r.POST("/test", func(c *gin.Context) {
c.Redirect(http.StatusFound, "/foo")
})

路由重定向,使用 HandleContext

r.GET("/test", func(c *gin.Context) {
    c.Request.URL.Path = "/test2"
    r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {
    c.JSON(200, gin.H{"hello": "world"})
})

原文地址:https://blog.csdn.net/qq_62408075/article/details/137278393

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!