Go语言中的gin框架Model + 上传文件(八)

本文介绍了在GinWeb框架中使用MVC模式组织应用,包括分离控制器、模型和视图的职责。同时详细阐述了如何处理多文件上传,包括设置HTML表单、在服务器端解析和保存上传文件,以及使用c.MultipartForm()和c.SaveUploadedFile()等方法。
摘要由CSDN通过智能技术生成

在Gin框架中,我们通常使用MVC模式来组织我们的应用程序。MVC代表Model-View-Controller,它将我们的应用程序分成了三个不同的层次,每个层次都有其特定的职责。

其中,Controller(控制器)负责处理用户请求,呈现视图,并调用Model(模型)来处理业务逻辑和数据。View(视图)则负责显示数据和用户界面。

在这种情况下,我们可以将控制器从模型代码中分离出来。这可以通过创建一个单独的目录,例如“controllers”,并在其中编写和处理所有控制器代码来完成。

在控制器中调用模型时,我们可以通过导入模型并调用其方法来处理所有业务逻辑和数据处理。同时,我们还可以使用Gin框架的模板渲染功能将模型返回的数据渲染到HTML视图中。这样就可以实现将模型的数据和业务逻辑与HTML视图完全分离的目标。

 在main.go 主入口 使用:

渲染到html页面,view层

以上是单文件,如何从 请求进入路由分组routers —> controllers —> template(view) 这样的流转顺序中夹杂着tools工具函数,具体

上传单文件可以看:

关于多文件上传,我们可以怎么操作?

在Gin框架中实现文件上传需要使用Multipart/Form数据类型。这种数据类型的请求被分为两个部分:文本字段和文件数据。另外,Gin框架内置了一个multipart.Form解析器c.MultipartForm(),方便我们对上传的文件进行处理。下面是具体的步骤:

1. 在HTML中,设置表单的enctype属性为multipart/form-data,这样服务器就会知道这是一个上传文件的请求。

注:c.Request.MultipartForm 是一个字段,用于访问原始请求对象中的多部分表单数据。通过该字段,您可以获取到一个 *multipart.Form 对象,您可以使用该对象的方法来解析和处理多部分表单数据。

2. 在服务器端,获取请求中的文件数据。使用c.Request.MultipartForm()来获取multipart.Form数据类型。这个方法会自动解析请求中的文本字段和文件数据。文件数据保存在server的内存或磁盘中,可以使用c.SaveUploadedFile()方法保存文件到指定的路径。

3. 如果要获取上传文件的元数据,比如文件名,可以使用c.Request.MultipartForm.File[filename],其中filename是指上传文件的表单字段名。这个方法返回的是一个multipart.FileHeader类型的指针,我们可以从其中获取文件的元数据。例如,如果我们要获取文件名,可以使用c.Request.MultipartForm.File[filename][0].Filename。

4. 对于上传多个文件,我们需要使用循环来处理每个上传文件的数据。下面是示例代码:

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

    router.POST("/upload", func(c *gin.Context) {
        //设置最大内存
        c.Request.ParseMultipartForm(32 << 20)

        //获取multipart/form-data数据类型
        form := c.Request.MultipartForm

        //获取上传的文件
        files := form.File["upload[]"] 

        //循环处理每个上传文件
        for _, file := range files {
            //保存文件到指定的路径
            err := c.SaveUploadedFile(file, "uploads/"+file.Filename)
            if err != nil {
                log.Println(err)
            }
        }

        c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
    })

    router.Run(":8080")
}

这段代码会处理名为"upload[]"的表单字段。对于每个上传文件,它会将文件保存到uploads目录下,并返回上传文件的数量。

除此之外还有一个方法【c.MultipartForm()】:c.MultipartForm() 则是一个方法,用于将原始请求对象中的多部分表单数据解析并绑定到 Gin 上下文对象中。该方法会返回一个 (*multipart.Form, error) 对象。

示例:

func uploadMultiFiles(c *gin.Context) {
	// 获取上传的多个文件
	form, _ := c.MultipartForm()
	files := form.File["file"]

	// 遍历保存多个文件
	for _, file := range files {
		filename := file.Filename
		dst := "./upload/" + filename
		// 创建目录
		err := os.MkdirAll(path.Dir(dst), os.ModePerm)
		if err != nil {
			c.String(http.StatusBadRequest, "CreateDir failed: "+err.Error())
			return
		}
		// 保存文件
		if err := c.SaveUploadedFile(file, dst); err != nil {
			c.String(http.StatusBadRequest, "Upload failed: "+err.Error())
			return
		}
	}
	c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
}

在上面的示例中,我们可以通过 c.MultipartForm() 方法获取上传的表单,并使用 form.File["file"] 的方式获取多个上传的文件。然后遍历这些文件,创建同名目录并保存文件。最后将响应消息写入响应体中。

同时两种多文件上传的使用区别:

c.Request.MultipartForm 和 c.MultipartForm() 是 Gin 框架中用于处理多部分表单数据的两个方法。它们在功能上是相似的,但使用方式略有不同。

  1. c.Request.MultipartForm:

    • 这是一个结构体字段,用于访问底层的 http.Request 对象中的多部分表单数据。
    • 它不需要函数调用,直接通过 c.Request.MultipartForm 就可以访问到解析后的表单数据。
    • 使用该方法时,需要在处理路由的函数中首先调用 c.Request.ParseMultipartForm 方法进行解析。
  2. c.MultipartForm():

    • 这是一个函数,用于返回请求中解析后的多部分表单数据。
    • 它需要函数调用,通过 c.MultipartForm() 的方式来获取表单数据。
    • 使用该方法时,Gin 框架会自动解析多部分表单数据,无需显式调用 c.Request.ParseMultipartForm

使用哪种方法取决于你的个人偏好和具体需求:

  • 如果你喜欢直接操作底层的 http.Request 对象并访问其中的多部分表单数据,可以使用 c.Request.MultipartForm
  • 如果你想通过简单的函数调用来获取解析后的多部分表单数据,可以使用 c.MultipartForm()

无论你选择哪种方法,你都需要在处理路由的函数中添加中间件,如 gin.Default() 或 gin.RouterGroup.Use(), 来确保 Gin 框架正确地解析和处理多部分表单数据。

补充一个比较直观的多文件上传,适用于少量的多文件的一个示例;

index.html 页面  View (视图层)

    <form action="/upfile/add" method="post" enctype="multipart/form-data">
        用户名:<input type="text" name="username" id="username">
        <br>
        头像1: <input type="file" name="file1" id="file1">
        <br>
        头像2: <input type="file" name="file2" id="file2">

        <br>
        <input type="submit" value="提交">
    </form>

controllers(控制器)

func (con UpfileControllers) Add(c *gin.Context) {
	username := c.PostForm("username")
	// 1.form表单上传file 文件如何接收?
	file1, err1 := c.FormFile("file1")
	file2, err2 := c.FormFile("file2")
	//err == nil 表示“没有发生错误” 就上传文件到本地  ./static/upload/ 拼接上文件名字
	if err1 == nil {
		dst1 := path.Join("./static/upload", file1.Filename)

		c.SaveUploadedFile(file1, dst1)
		fmt.Println("file文件------")
	}
	if err2 == nil {
		dst2 := path.Join("./static/upload", file2.Filename)

		c.SaveUploadedFile(file2, dst2)
		fmt.Println("file文件------")
	}

	c.String(200, "上传文件--string-success-用户%v-图片%v \n", username, file1.Filename, file2.Filename)

}


// 终端输出

上传文件--string-success-用户eee-图片红点奖.png| 图片logo.png  



routers (路由)upfileRouter.go

package routers

import (
	"***/controllers/upfile"
	"***/middlewares"

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

func UpfileRouterInit(r *gin.Engine) {
	upfileRouter := r.Group("/upfile", middlewares.InitMiddleWares) //添加一个中间件测试一下
	{
		upfileRouter.GET("/", upfile.UpfileControllers{}.Index)
		upfileRouter.POST("/add", upfile.UpfileControllers{}.Add)
	}
}

对于以上就是多文件的另一种使用的体现。

希望对于你的学习有帮助!共勉之……

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为您提供一些关于使用 Golang Gin 框架进行项目实战的建议。 首先,您需要安装 Golang 和 Gin 框架。安装过程可以参考官方文档进行操作。然后,您可以按照以下步骤进行项目实战: 1. 创建项目结构 在您的 GOPATH 目录下创建一个新的项目文件夹。通常情况下,您需要为项目创建以下子文件夹: ``` . ├── main.go ├── config │ ├── config.go │ └── ... ├── controller │ ├── home_controller.go │ └── ... ├── middleware │ ├── auth.go │ └── ... ├── model │ ├── user.go │ └── ... ├── router │ ├── router.go │ └── ... └── service ├── user_service.go └── ... ``` 2. 创建路由 在 router 文件夹创建一个 router.go 文件,并编写以下代码: ```go package router import ( "github.com/gin-gonic/gin" "your-project/controller" "your-project/middleware" ) func SetupRouter() *gin.Engine { r := gin.Default() // 间件 r.Use(middleware.AuthMiddleware()) // 路由 r.GET("/", controller.HomePageHandler) return r } ``` 在上面的代码,我们使用了 gin 框架gin.Default() 函数来创建一个默认的 gin.Engine 实例,并使用间件来进行身份验证。然后我们定义了一个路由,将根路径映射到 HomePageHandler 方法。 3. 创建控制器 在 controller 文件夹创建 home_controller.go 文件,并编写以下代码: ```go package controller import ( "github.com/gin-gonic/gin" "your-project/service" ) func HomePageHandler(c *gin.Context) { users := service.GetAllUsers() c.JSON(200, users) } ``` 在上面的代码,我们定义了一个 HomePageHandler 方法,它接收一个 gin.Context 对象作为参数,并使用 service 层的 GetAllUsers 函数获取所有用户的数据。然后我们使用 JSON 方法将数据以 JSON 格式返回给客户端。 4. 创建服务层 在 service 文件夹创建 user_service.go 文件,并编写以下代码: ```go package service import "your-project/model" func GetAllUsers() []*model.User { // TODO: 查询数据库获取所有用户数据 return []*model.User{} } ``` 在上面的代码,我们定义了一个 GetAllUsers 函数,它返回一个包含所有用户数据的切片。在实际项目,我们需要查询数据库来获取这些数据。 5. 创建模型 在 model 文件夹创建 user.go 文件,并编写以下代码: ```go package model type User struct { ID int `json:"id"` Name string `json:"name"` Age int `json:"age"` } ``` 在上面的代码,我们定义了一个 User 结构体,它包含三个字段:ID、Name 和 Age。这些字段将用于存储每个用户的信息。 6. 创建配置文件 在 config 文件夹创建 config.go 文件,并编写以下代码: ```go package config const ( DB_HOST = "localhost" DB_PORT = "3306" DB_USERNAME = "root" DB_PASSWORD = "password" DB_NAME = "your-database-name" ) ``` 在上面的代码,我们定义了一些常量,用于存储数据库配置信息。这些常量将在连接数据库时使用。 7. 连接数据库 在 service 层的 GetAllUsers 函数,我们需要连接数据库来获取所有用户数据。可以使用以下代码来连接 MySQL 数据库: ```go package service import ( "database/sql" "fmt" "your-project/config" "your-project/model" ) func GetAllUsers() []*model.User { // 连接数据库 db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", config.DB_USERNAME, config.DB_PASSWORD, config.DB_HOST, config.DB_PORT, config.DB_NAME, )) if err != nil { panic(err) } defer db.Close() // 查询所有用户数据 rows, err := db.Query("SELECT * FROM users") if err != nil { panic(err) } // 解析查询结果 users := []*model.User{} for rows.Next() { user := &model.User{} err := rows.Scan(&user.ID, &user.Name, &user.Age) if err != nil { panic(err) } users = append(users, user) } return users } ``` 在上面的代码,我们使用 sql.Open 函数来打开 MySQL 数据库连接。然后我们使用 db.Query 函数来查询所有用户数据,并使用 rows.Scan 函数将查询结果解析为 User 结构体的切片。 以上就是使用 Golang Gin 框架进行项目实战的流程。当然,在实际项目,您需要根据自己的需求进行相应的修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

匠造一知识

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值