在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 框架中用于处理多部分表单数据的两个方法。它们在功能上是相似的,但使用方式略有不同。
-
c.Request.MultipartForm
:- 这是一个结构体字段,用于访问底层的
http.Request
对象中的多部分表单数据。 - 它不需要函数调用,直接通过
c.Request.MultipartForm
就可以访问到解析后的表单数据。 - 使用该方法时,需要在处理路由的函数中首先调用
c.Request.ParseMultipartForm
方法进行解析。
- 这是一个结构体字段,用于访问底层的
-
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)
}
}
对于以上就是多文件的另一种使用的体现。
希望对于你的学习有帮助!共勉之……