参考地址:
单文件
官方案例:
func main() {
router := gin.Default()
// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// 单文件
file, _ := c.FormFile("file")
log.Println(file.Filename)
dst := "./" + file.Filename
// 上传文件至指定的完整文件路径
c.SaveUploadedFile(file, dst)
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
router.Run(":8080")
}
操作案例:
我们选择之前的userRoute以及userAddControl进行操作,结合模板(新创建模板)进行渲染
1、渲染模板:
在templates/admin/下创建模板useradd.html
placeholder底部显示
{{ define "admin/useradd.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>----Gin Framek单文件上传测试----</h2>
<br>
<br>
<!-- action是最后我们在点击提交后使用POST去服务器搞资源的操作路由 -->
<form action="/admin/user/fileUpload" method="post"></form>
<input type="text" name = "username" placeholder="用户名" />
<br>
<br>
<input type="file" value="photo" placeholder="人物肖像" />
<br> <br>
<input type="submit" value="提交">
</body>
</html>
{{ end }}
2、控制器调整:
package admin
import (
"net/http"
"github.com/gin-gonic/gin"
)
type UserAddController struct {
BaseController
}
func (con UserAddController) Index(c *gin.Context) {
con.success(c)
}
func (con UserAddController) Add(c *gin.Context) {
c.HTML(http.StatusOK ,"admin/useradd.html",gin.H{
})
}
func (con UserAddController) Edit(c *gin.Context) {
c.String(200, "用户列表-Edit------")
}
3、查看路由接入口:
package routers
import (
"gindemo04/controllers/admin"
"gindemo04/middle"
"github.com/gin-gonic/gin"
)
func AdminRoutersInit(r *gin.Engine) {
//middlewares.InitMiddleware中间件
adminRouters := r.Group("/admin", middle.InitMiddleware)
{
adminRouters.GET("/", admin.IndexController{}.Index)
adminRouters.GET("/user", admin.UserAddController{}.Index)
adminRouters.GET("/user/add", admin.UserAddController{}.Add)
adminRouters.GET("/user/edit", admin.UserAddController{}.Edit)
}
}
4、展示页面测试:
Documenthttp://127.0.0.1:8210/admin/user/add
点击提交之后,会转到之前模板渲染操作的action操作
而要实现文件的正确上传
需要在上传文件的 form 表单上面需要加入 enctype="multipart/form-data"
点击提交后,转到在action内的路由操作,注意几则:
- 要在 表单内,不然跳转会出问题
- 控制器内的方法需要大写首字母,不然成为私有方法,在路由内无法调用
- 渲染的form后面需要加enctype="multipart/form-data
- 一一对应,路由,控制器,渲染模板
5、修改渲染的模板加入enctype
{{ define "admin/useradd.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FileUploadtest</title>
</head>
<body>
<h2>----Gin Framek单文件上传测试----</h2>
<form action="/admin/user/fileUpload" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username" placeholder="用户名" />
<br>
<br>
人物像:<input type="file" name="photo" />
<br> <br>
<input type="submit" value="提交">
</form>
</body>
</html>
{{ end }}
6、添加对应的控制器方法
7、路由操作调用方法
package routers
import (
"gindemo04/controllers/admin"
"gindemo04/middle"
"github.com/gin-gonic/gin"
)
func AdminRoutersInit(r *gin.Engine) {
//middlewares.InitMiddleware中间件
adminRouters := r.Group("/admin", middle.InitMiddleware)
{
adminRouters.GET("/", admin.IndexController{}.Index)
adminRouters.GET("/user", admin.UserAddController{}.Index)
adminRouters.GET("/user/add", admin.UserAddController{}.Add)
adminRouters.POST("/user/fileUpload", admin.UserAddController{}.FileUpload)
}
}
8、测试从前端页面到POST服务拉取资源
自动跳转(仅测试,接下来实现上传)
9、真实上传操作(修改跳转的页面路由)
在static目录下创建一个文件images
以及修改后的控制器
package admin
import (
"net/http"
"path"
"github.com/gin-gonic/gin"
)
type UserAddController struct {
BaseController
}
func (con UserAddController) Index(c *gin.Context) {
con.success(c)
}
func (con UserAddController) Add(c *gin.Context) {
c.HTML(http.StatusOK, "admin/useradd.html", gin.H{})
}
func (con UserAddController) FileUpload(c *gin.Context) {
username := c.PostForm("username")
file, err := c.FormFile("photo")
dest := path.Join("./static/images", file.Filename)
if err == nil {
c.SaveUploadedFile(file, dest)
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"username": username,
"dest": dest,
})
}
10、测试文件上传
有了一个图片
多文件上传(上传的file名称不同的操作)
1、修改渲染模板
创建useredit的html文件
{{ define "admin/useredit.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FileUploadtest</title>
</head>
<body>
<h2>----Gin Framek多文件上传测试(不同名称)----</h2>
<!-- 配置路由/admin/user/fileEdit -->
<form action="/admin/user/fileEdit" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username" placeholder="用户名" />
<br>
<br>
人物像1:<input type="file" name="photo1" />
<br>
<br>
人物像2:<input type="file" name="photo2" />
<br> <br>
<input type="submit" value="提交">
</form>
</body>
</html>
{{ end }}
2、控制器调整
package admin
import (
"net/http"
"path"
"github.com/gin-gonic/gin"
)
type UserAddController struct {
BaseController
}
func (con UserAddController) Index(c *gin.Context) {
con.success(c)
}
func (con UserAddController) Add(c *gin.Context) {
c.HTML(http.StatusOK, "admin/useradd.html", gin.H{})
}
func (con UserAddController) FileUpload(c *gin.Context) {
username := c.PostForm("username")
file, err := c.FormFile("photo")
dest := path.Join("./static/images", file.Filename)
if err == nil {
c.SaveUploadedFile(file, dest)
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"username": username,
"dest": dest,
})
}
func (con UserAddController) Edit(c *gin.Context) {
c.HTML(http.StatusOK, "admin/useredit.html", gin.H{})
}
func (con UserAddController) FileEdit(c *gin.Context) {
username := c.PostForm("username")
file1, err1 := c.FormFile("photo1")
dest1 := path.Join("./static/images", file1.Filename)
if err1 == nil {
c.SaveUploadedFile(file1, dest1)
}
file2, err2 := c.FormFile("photo2")
dest2 := path.Join("./static/images", file2.Filename)
if err2 == nil {
c.SaveUploadedFile(file2, dest2)
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"username": username,
"dest1": dest1,
"dest2": dest2,
})
}
3、路由接口配置
package routers
import (
"gindemo04/controllers/admin"
"gindemo04/middle"
"github.com/gin-gonic/gin"
)
func AdminRoutersInit(r *gin.Engine) {
//middlewares.InitMiddleware中间件
adminRouters := r.Group("/admin", middle.InitMiddleware)
{
adminRouters.GET("/", admin.IndexController{}.Index)
adminRouters.GET("/user", admin.UserAddController{}.Index)
adminRouters.GET("/user/add", admin.UserAddController{}.Add)
adminRouters.POST("/user/fileUpload", admin.UserAddController{}.FileUpload)
adminRouters.POST("/user/fileEdit", admin.UserAddController{}.FileEdit)
adminRouters.GET("/user/edit", admin.UserAddController{}.Edit)
adminRouters.GET("/article", admin.ArticleController{}.Index)
adminRouters.GET("/article/add", admin.ArticleController{}.Add)
adminRouters.GET("/article/edit", admin.ArticleController{}.Edit)
}
}
4、进行测试
多文件上传(上传的file名称相同的操作)
1、修改渲染模板
{{ define "admin/useradd.html" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FileUploadtest</title>
</head>
<body>
<h2>----Gin Framek单文件上传测试----</h2>
<form action="/admin/user/fileUpload" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username" placeholder="用户名" />
<br>
<br>
人物像1:<input type="file" name="photo[]" />
<br> <br>
人物像2:<input type="file" name="photo[]" />
<br> <br>
<input type="submit" value="提交">
</form>
</body>
</html>
{{ end }}
2、控制器调整
MultipartForm是经过解析的多部分表单,包括文件上传。
package admin
import (
"net/http"
"path"
"github.com/gin-gonic/gin"
)
type UserAddController struct {
BaseController
}
func (con UserAddController) Index(c *gin.Context) {
con.success(c)
}
func (con UserAddController) Add(c *gin.Context) {
c.HTML(http.StatusOK, "admin/useradd.html", gin.H{})
}
func (con UserAddController) FileUpload(c *gin.Context) {
username := c.PostForm("username")
form,_ := c.MultipartForm()
files := form.File["photo[]"]
for _,file := range files{
dest := path.Join("./static/images", file.Filename)
c.SaveUploadedFile(file, dest)
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"username": username,
})
}
3、路由接口配置
4、测试