3.1goweb框架gin上

Gin 是一个用 Go 语言编写的轻量级 Web 框架,以其高性能、简洁易用和良好的扩展性而受到广泛欢迎。

安装与初始化

在使用 Gin 之前,你需要安装它。可以使用以下命令进行安装:

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

在代码中初始化 Gin 引擎的示例:

package main

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

func main() {
    // 创建一个默认的 Gin 引擎,包含日志和恢复中间件
    r := gin.Default()

    // 启动服务器,监听 8080 端口
    r.Run(":8080")
}

gin.Default() 方法会自动帮你配置 Logger 和 Recovery 中间件。Logger 用于记录请求日志,Recovery 用于捕获并处理 panic,防止程序因 panic 而崩溃。 想要自定义中间件的顺序和配置,也可以手动配置 Recovery 中间件。示例代码如下

package main

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

func main() {
    // 创建一个空的 Gin 引擎
    r := gin.New()

    // 手动添加 Recovery 中间件
    r.Use(gin.Recovery())

    r.GET("/", func(c *gin.Context) {
        // 模拟一个 panic
        panic("Something went wrong!")
    })

    r.Run(":8080")
}

在这个例子中,使用 gin.New() 创建了一个空的 Gin 引擎,然后通过 r.Use(gin.Recovery()) 手动添加了 Recovery 中间件。同样,当访问 / 路由触发 panic 时,程序不会崩溃

你还可以自定义 Recovery 中间件的行为,例如自定义错误处理逻辑和响应信息。示例代码如下:

package main

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

func customRecovery() gin.HandlerFunc {
    return func(c *gin.Context) {
        defer func() {
            if err := recover(); err != nil {
                // 打印错误信息和堆栈跟踪
                debug.PrintStack()

                // 返回自定义的错误响应
                c.JSON(http.StatusInternalServerError, gin.H{
                    "error": "Internal Server Error",
                })
                // 终止当前请求处理
                c.Abort()
            }
        }()
        // 继续处理请求
        c.Next()
    }
}

func main() {
    r := gin.New()

    // 使用自定义的 Recovery 中间件
    r.Use(customRecovery())

    r.GET("/", func(c *gin.Context) {
        panic("Something went wrong!")
    })

    r.Run(":8080")
}

 

路由

Gin 支持多种 HTTP 方法(如 GET、POST、PUT、DELETE 等)的路由设置。

基本路由示例
package main

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

func main() {
    r := gin.Default()

    // 定义一个 GET 请求的路由
    r.GET("/hello", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "message": "Hello, World!",
        })
    })

    r.Run(":8080")
}

在上述代码中,我们定义了一个 /hello 的 GET 请求路由,当客户端访问该路由时,会返回一个 JSON 格式的响应。

路由参数

Gin 支持在路由中使用参数。

package main

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

func main() {
    r := gin.Default()

    // 定义一个带有参数的路由
    r.GET("/users/:id", func(c *gin.Context) {
        id := c.Param("id")
        c.JSON(http.StatusOK, gin.H{
            "user_id": id,
        })
    })

    r.Run(":8080")
}

这里的 :id 是一个参数,客户端访问 /users/123 时,服务器会将 123 作为 id 参数进行处理。

中间件

中间件是 Gin 中非常重要的特性,它可以在请求处理前后执行一些操作,如日志记录、身份验证等。

自定义中间件示例
package main

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

// 自定义中间件函数
func myMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 在请求处理前执行操作
        c.Set("key", "value")
        // 继续处理请求
        c.Next()
        // 在请求处理后执行操作
    }
}

func main() {
    r := gin.Default()

    // 使用自定义中间件
    r.Use(myMiddleware())

    r.GET("/test", func(c *gin.Context) {
        value, exists := c.Get("key")
        if exists {
            c.JSON(http.StatusOK, gin.H{
                "message": "Middleware value: " + value.(string),
            })
        }
    })

    r.Run(":8080")
}

在这个例子中,我们定义了一个自定义中间件 myMiddleware,它在请求处理前设置了一个键值对,在处理 /test 路由时可以获取到这个值。

分组路由

分组路由可以将一组相关的路由进行分组管理,方便代码组织和维护。

package main

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

func main() {
    r := gin.Default()

    // 创建一个路由组
    v1 := r.Group("/v1")
    {
        v1.GET("/users", func(c *gin.Context) {
            c.JSON(http.StatusOK, gin.H{
                "version": "v1",
                "resource": "users",
            })
        })
        v1.GET("/posts", func(c *gin.Context) {
            c.JSON(http.StatusOK, gin.H{
                "version": "v1",
                "resource": "posts",
            })
        })
    }

    r.Run(":8080")
}

这里我们创建了一个 /v1 的路由组,将 /v1/users 和 /v1/posts 路由放在这个组中。

错误处理

Gin 提供了简单的错误处理机制,可以方便地处理请求过程中出现的错误。

package main

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

func main() {
    r := gin.Default() // gin.Default() 已经包含了 Recovery 中间件

    r.GET("/panic", func(c *gin.Context) {
        // 模拟一个 panic
        panic("Panic occurred")
    })

    r.Run(":8080")
}

当使用 gin.Default() 创建 Gin 引擎时,会自动包含 Logger 和 Recovery 中间件。Recovery 中间件会捕获 panic,并返回一个 500 状态码的错误响应。

c.Abort()

c.Abort() 方法的主要功能是停止当前请求在中间件链中的继续执行,也就是说,后续还未执行的中间件和处理函数都不会再被调用。

package main

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

func middleware1(c *gin.Context) {
    // 模拟一些处理逻辑
    c.JSON(http.StatusOK, gin.H{"message": "Middleware 1 executed"})
    // 终止请求处理流程
    c.Abort()
}

func middleware2(c *gin.Context) {
    // 由于 middleware1 中调用了 c.Abort(),此函数不会被执行
    c.JSON(http.StatusOK, gin.H{"message": "Middleware 2 executed"})
}

func main() {
    r := gin.Default()

    r.GET("/", middleware1, middleware2)

    r.Run(":8080")
}

在这个例子中,当客户端访问根路径 / 时,middleware1 会先被执行,在 middleware1 里调用了 c.Abort(),这就导致 middleware2 不会被执行。

在错误处理的场景中,c.Abort() 常常和 c.JSON()  一起使用,以此返回错误响应并终止请求处理。

 

静态文件服务

Gin 可以方便地提供静态文件服务,如 HTML、CSS、JavaScript 等文件。

package main

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

func main() {
    r := gin.Default()

    // 提供静态文件服务
    r.Static("/static", "./static")

    r.Run(":8080")
}

这里将 ./static 目录下的文件映射到 /static 路径下,客户端可以通过 /static 访问这些静态文件。

 使用 Gin 框架实现文件上传和下载

 Gin 框架提供了更简洁的 API 来处理文件上传和下载

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"os"
)

func uploadFile(c *gin.Context) {
	// 单文件上传
	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(400, gin.H{
			"error": err.Error(),
		})
		return
	}

	// 创建上传目录
	if _, err := os.Stat("./uploads"); os.IsNotExist(err) {
		err := os.MkdirAll("./uploads", 0755)
		if err != nil {
			log.Fatal(err)
		}
	}

	// 保存文件
	filePath := "./uploads/" + file.Filename
	if err := c.SaveUploadedFile(file, filePath); err != nil {
		c.JSON(500, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(200, gin.H{
		"message": fmt.Sprintf("'%s' uploaded successfully", file.Filename),
	})
}

func main() {
	r := gin.Default()

	// 定义上传文件的路由
	r.POST("/upload", uploadFile)

	// 启动服务器
	if err := r.Run(":8080"); err != nil {
		log.Fatal(err)
	}
}    
package main

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

func downloadFile(c *gin.Context) {
	filePath := "./uploads/test.txt" // 替换为实际要下载的文件路径
	c.File(filePath)
}

func main() {
	r := gin.Default()

	// 定义下载文件的路由
	r.GET("/download", downloadFile)

	// 启动服务器
	if err := r.Run(":8080"); err != nil {
		log.Fatal(err)
	}
}    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chxii

小小打赏,大大鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值