vault backup: 2026-06-07 11:08:10
This commit is contained in:
@@ -0,0 +1,362 @@
|
||||
---
|
||||
tags:
|
||||
- Go
|
||||
- golang
|
||||
- gin
|
||||
- web框架
|
||||
- http
|
||||
---
|
||||
|
||||
# Gin
|
||||
|
||||
Gin是一个用Go语言编写的高性能Web框架,以其高效的路由系统和优秀的性能著称。本文将详细介绍如何使用Gin框架开发Web应用。
|
||||
|
||||
## 安装Gin
|
||||
|
||||
首先,我们需要安装Gin框架。可以使用以下命令:
|
||||
|
||||
```bash
|
||||
go get -u github.com/gin-gonic/gin
|
||||
```
|
||||
|
||||
## 基本使用
|
||||
|
||||
### 创建HTTP服务器
|
||||
|
||||
使用Gin创建一个基本的HTTP服务器非常简单:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 创建默认的路由引擎
|
||||
r := gin.Default()
|
||||
|
||||
// 注册一个GET路由
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "pong",
|
||||
})
|
||||
})
|
||||
|
||||
// 启动HTTP服务,默认在0.0.0.0:8080启动服务
|
||||
r.Run()
|
||||
}
|
||||
```
|
||||
|
||||
### 路由参数
|
||||
|
||||
Gin支持多种路由参数形式:
|
||||
|
||||
```go
|
||||
// 获取get请求的路径参数,参数名为name
|
||||
r.GET("/user/:name", func(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
c.String(http.StatusOK, "Hello %s", name)
|
||||
})
|
||||
|
||||
// 获取get请求的路径参数,参数名为name,age,age的默认值为20
|
||||
r.GET("/users", func(c *gin.Context) {
|
||||
name := c.Query("name") // 获取name参数
|
||||
age := c.DefaultQuery("age", "20") // 获取age参数,默认值为20
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"name": name,
|
||||
"age": age,
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### 处理表单数据
|
||||
|
||||
Gin可以轻松处理POST请求中的表单数据:
|
||||
|
||||
```go
|
||||
r.POST("/form", func(c *gin.Context) {
|
||||
// 获取表单参数
|
||||
username := c.PostForm("username")
|
||||
password := c.DefaultPostForm("password", "")
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"username": username,
|
||||
"password": password,
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### 处理JSON数据
|
||||
|
||||
Gin可以轻松处理POST请求中的JSON数据:
|
||||
|
||||
```go
|
||||
// 定义请求体结构
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
|
||||
r.POST("/login", func(c *gin.Context) {
|
||||
var login LoginRequest
|
||||
|
||||
// 将请求体绑定到结构体
|
||||
if err := c.BindJSON(&login); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 处理登录逻辑
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "登录成功",
|
||||
"username": login.Username,
|
||||
})
|
||||
})
|
||||
|
||||
// 也可以直接使用map接收JSON数据
|
||||
r.POST("/raw", func(c *gin.Context) {
|
||||
var data map[string]interface{}
|
||||
|
||||
if err := c.BindJSON(&data); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, data)
|
||||
})
|
||||
```
|
||||
|
||||
在上面的示例中:
|
||||
1. 使用结构体接收JSON数据时,可以通过tag来指定字段的验证规则
|
||||
2. `binding:"required"`表示该字段是必需的
|
||||
3. 也可以使用map来接收不固定结构的JSON数据
|
||||
4. `c.BindJSON()`会自动检查Content-Type是否为application/json
|
||||
|
||||
### 上传文件
|
||||
|
||||
Gin支持单文件和多文件上传:
|
||||
|
||||
```go
|
||||
// 单文件上传
|
||||
r.POST("/upload", func(c *gin.Context) {
|
||||
file, _ := c.FormFile("file")
|
||||
|
||||
// 保存文件
|
||||
c.SaveUploadedFile(file, "./"+file.Filename)
|
||||
|
||||
c.String(http.StatusOK, "File %s uploaded successfully", file.Filename)
|
||||
})
|
||||
|
||||
// 多文件上传
|
||||
r.POST("/uploads", func(c *gin.Context) {
|
||||
form, _ := c.MultipartForm()
|
||||
files := form.File["files"]
|
||||
|
||||
for _, file := range files {
|
||||
c.SaveUploadedFile(file, "./"+file.Filename)
|
||||
}
|
||||
|
||||
c.String(http.StatusOK, "%d files uploaded successfully", len(files))
|
||||
})
|
||||
```
|
||||
|
||||
### 中间件
|
||||
|
||||
Gin的中间件可以在请求处理过程中执行一些公共的操作:
|
||||
|
||||
```go
|
||||
// 定义一个中间件
|
||||
func Logger() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
t := time.Now()
|
||||
|
||||
// 在请求之前
|
||||
|
||||
c.Next()
|
||||
|
||||
// 在请求之后
|
||||
latency := time.Since(t)
|
||||
log.Printf("请求处理时间: %v", latency)
|
||||
}
|
||||
}
|
||||
|
||||
// 使用中间件
|
||||
r.Use(Logger())
|
||||
```
|
||||
|
||||
### 分组路由
|
||||
|
||||
Gin支持路由分组,可以更好地组织API:
|
||||
|
||||
```go
|
||||
// 创建v1版本的路由组
|
||||
v1 := r.Group("/v1")
|
||||
{
|
||||
v1.POST("/login", loginEndpoint)
|
||||
v1.POST("/submit", submitEndpoint)
|
||||
v1.POST("/read", readEndpoint)
|
||||
}
|
||||
|
||||
// 创建v2版本的路由组
|
||||
v2 := r.Group("/v2")
|
||||
{
|
||||
v2.POST("/login", loginEndpointV2)
|
||||
v2.POST("/submit", submitEndpointV2)
|
||||
v2.POST("/read", readEndpointV2)
|
||||
}
|
||||
```
|
||||
|
||||
## 完整示例
|
||||
|
||||
以下是一个完整的示例,展示了如何使用Gin框架创建一个简单的RESTful API服务:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// User 用户模型
|
||||
type User struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age"`
|
||||
}
|
||||
|
||||
// 模拟数据库
|
||||
var users = []User{
|
||||
{ID: 1, Name: "张三", Age: 25},
|
||||
{ID: 2, Name: "李四", Age: 30},
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 创建默认的路由引擎
|
||||
r := gin.Default()
|
||||
|
||||
// 注册路由
|
||||
r.GET("/users", getUsers)
|
||||
r.GET("/users/:id", getUserByID) // 这里的冒号表示路径参数,可以通过c.Param("id")获取
|
||||
r.POST("/users", createUser)
|
||||
r.PUT("/users/:id", updateUser)
|
||||
r.DELETE("/users/:id", deleteUser)
|
||||
|
||||
// 启动http服务器,监听8080端口
|
||||
if err := r.Run(":8080"); err != nil {
|
||||
log.Fatalf("Server error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有用户
|
||||
func getUsers(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, users)
|
||||
}
|
||||
|
||||
// 根据ID获取用户
|
||||
func getUserByID(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
for _, user := range users {
|
||||
if string(user.ID) == id {
|
||||
c.JSON(http.StatusOK, user)
|
||||
return
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusNotFound, gin.H{"message": "User not found"})
|
||||
}
|
||||
|
||||
// 创建用户
|
||||
func createUser(c *gin.Context) {
|
||||
var newUser User
|
||||
if err := c.BindJSON(&newUser); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
users = append(users, newUser)
|
||||
c.JSON(http.StatusCreated, newUser)
|
||||
}
|
||||
|
||||
// 更新用户
|
||||
func updateUser(c *gin.Context) {
|
||||
// 获取路径参数中的ID
|
||||
id := c.Param("id")
|
||||
var updatedUser User
|
||||
|
||||
// 绑定请求体中的JSON数据到updatedUser
|
||||
if err := c.BindJSON(&updatedUser); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
for i, user := range users {
|
||||
if string(user.ID) == id {
|
||||
users[i] = updatedUser
|
||||
c.JSON(http.StatusOK, updatedUser)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusNotFound, gin.H{"message": "User not found"})
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
func deleteUser(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
for i, user := range users {
|
||||
if string(user.ID) == id {
|
||||
users = append(users[:i], users[i+1:]...)
|
||||
c.JSON(http.StatusOK, gin.H{"message": "User deleted"})
|
||||
return
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusNotFound, gin.H{"message": "User not found"})
|
||||
}
|
||||
```
|
||||
|
||||
### 程序测试
|
||||
|
||||
使用curl命令测试API:
|
||||
|
||||
```bash
|
||||
# 获取所有用户
|
||||
curl http://localhost:8080/users
|
||||
|
||||
# 获取指定用户
|
||||
curl http://localhost:8080/users/1
|
||||
|
||||
# 创建用户
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"id":3,"name":"王五","age":35}' http://localhost:8080/users
|
||||
|
||||
# 更新用户
|
||||
curl -X PUT -H "Content-Type: application/json" -d '{"id":1,"name":"张三丰","age":26}' http://localhost:8080/users/1
|
||||
|
||||
# 删除用户
|
||||
curl -X DELETE http://localhost:8080/users/2
|
||||
```
|
||||
|
||||
### 代码说明
|
||||
|
||||
1. **路由设置**:使用`gin.Default()`创建路由引擎,并注册了基本的RESTful API路由。
|
||||
|
||||
2. **数据模型**:定义了`User`结构体作为数据模型,并使用切片模拟数据库存储。
|
||||
|
||||
3. **请求处理**:实现了增删改查(CRUD)的基本操作,包括:
|
||||
- GET /users:获取所有用户
|
||||
- GET /users/:id:获取指定用户
|
||||
- POST /users:创建新用户
|
||||
- PUT /users/:id:更新用户
|
||||
- DELETE /users/:id:删除用户
|
||||
|
||||
4. **错误处理**:对各种可能的错误情况进行了处理,并返回适当的HTTP状态码。
|
||||
|
||||
## 小结
|
||||
|
||||
这篇文章简单介绍了Gin框架的基本使用方法,包括路由配置、参数获取、中间件使用等内容。如需了解Gin框架更详细的用法,可以参考:[Gin框架官方文档](https://gin-gonic.com/zh-cn/docs/)
|
||||
Reference in New Issue
Block a user