일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- create table
- postgresql
- ftp
- 실행권한
- insert
- ubuntu
- nmap
- appium
- appium server
- nGrinder
- STF_PortForwarding
- rethinkdb
- STF
- mysql
- openpyxl
- kitura
- Jupyter Notebook
- PYTHON
- Materials
- nohup
- GoCD
- 28015
- centos
- Jupyter
- postgres
- ssh
- port forwarding
- SWIFT
- sshpass
- perfect
- Today
- Total
don't stop believing
Upload files 본문
이번에는 파일 업로드를 해보겠습니다.
https://github.com/gin-gonic/gin#upload-files
파일 하나 올리는 것과, 여러개를 동시에 올리는 것을 해보겠습니다.
우선 파일을 올릴 수 있는 html 파일을 아래와 같이 만들어 줍니다. 저는 uploadfiles.html로 만들었습니다.
위치는 templates 폴더 안에 위치합니다.
123456789101112<html><head><title>Tongchun's go gin</title></head><body><h2>page: {{ .page }}</h2><form action="http://localhost:8080/upload" method="POST" enctype="multipart/form-data">upload file: <input type="file" name="file"><input type="submit" value="Submit"></form></body></html>
이번에는 server.go 내용입니다.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364package mainimport ("fmt""log""net/http""path/filepath""github.com/gin-gonic/gin")func setupRouter() *gin.Engine {// Disable Console Color// gin.DisableConsoleColor()r := gin.Default()r.GET("/uploadpage", func(c *gin.Context) {title := "upload single file"c.HTML(http.StatusOK, "uploadfile.html", gin.H{"page": title,})})r.POST("/upload", uploadSingle)return r}func uploadSingle(c *gin.Context) {// single filefile, err := c.FormFile("file")if err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))return}log.Println(file.Filename)// Upload the file to specific dst.filename := filepath.Base(file.Filename)uploadPath := "./example/upload/" + filenamelog.Println(filename)if err := c.SaveUploadedFile(file, uploadPath); err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("upload file err: %s", err.Error()))return}c.JSON(200, gin.H{"status": "posted","file name": file.Filename,})}func main() {r := setupRouter()// Set a lower memory limit for multipart forms (default is 32 MiB)r.MaxMultipartMemory = 8 << 20 // 8 MiBr.Static("/files", "./example/upload")r.LoadHTMLGlob("./example/templates/*")// Listen and Server in 0.0.0.0:8080r.Run(":8080")}
먼저 main() 함수에 아래와 같이 MaxMultipartMemory를 설정합니다.
// Set a lower memory limit for multipart forms (default is 32 MiB)
r.MaxMultipartMemory = 8 << 20 // 8 MiB
비트 이동과 메모리 설정의 경우 아래 포스트를 참고할 수 있습니다.
https://dejavuqa.tistory.com/328
setupRouter() 함수안에 파일 업로드를 할수 있는 GET method의 경로를 추가합니다.
r.GET("/uploadpage", func(c *gin.Context) {
title := "upload single file"
c.HTML(http.StatusOK, "uploadfile.html", gin.H{
"page": title,
})
})
server.go를 실행하고 localhost:8080/uploadpage 를 호출하면 파일을 업로드 할 수 있는 페이지가 호출됩니다.
html 페이지에서 submit 버튼을 클릭하면 loalhost:8080/upload 로 파일을 업로드 하게 됩니다.
/upload 경로의 handler 함수로 uploadSingle() 함수가 호출됩니다.
업로드된 파일은 설정된 경로에 파일 이름 그대로 저장이 됩니다.
실행해 보겠습니다.
123456789101112131415161718$ go run example/server.go[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.- using env: export GIN_MODE=release- using code: gin.SetMode(gin.ReleaseMode)[GIN-debug] GET /uploadpage --> main.setupRouter.func1 (3 handlers)[GIN-debug] POST /upload --> main.uploadSingle (3 handlers)[GIN-debug] GET /files/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)[GIN-debug] HEAD /files/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)[GIN-debug] Loaded HTML Templates (4):- note.html- uploadfile.html-- index.html[GIN-debug] Listening and serving HTTP on :8080
localhost:8080/uploadpage 를 호출하고 업로드할 파일을 선택합니다.
Submit을 클릭해 파일을 업로드 합니다.
파일이 재대로 올라갔는지 서버에서도 확인해 봅니다.
12345$ ll ./example/upload/total 37136drwxr-xr-x 4 tongchunkim staff 128B 2 28 16:46 .drwxr-xr-x 6 tongchunkim staff 192B 2 27 16:37 ..-rw-r--r-- 1 tongchunkim staff 34K 2 28 16:46 traffic_control.zip
이번에는 파일 3개와 Post Form 데이터를 동시에 받아보겠습니다.
먼저 아래와 같이 html 파일을 수정합니다.
12345678910111213141516<html><head><title>Tongchun's go gin</title></head><body><h2>page: {{ .page }}</h2><form action="http://localhost:8080/multiupload" method="POST" enctype="multipart/form-data">first name: <input type="text" name="first_name"><br>family name: <input type="text" name="family_name"><br>upload file 1: <input type="file" name="file"><br>upload file 2: <input type="file" name="file"><br>upload file 3: <input type="file" name="file"><br><input type="submit" value="Submit"></form></body></html>
확인할 사항은 file을 넘기는 input의 name을 file이라고 모두 동일하게 합니다.
그러면 3개의 file 데이터는 슬라이스 타입으로 전달되게 됩니다.
그리고 server.go 에서는 아래와 같이 route를 추가했습니다.
r.POST("/multiupload", uploadMultifile)
uploadMultifile 핸들러 함수는 아래와 같습니다.
12345678910111213141516171819202122232425262728293031323334353637func uploadMultifile(c *gin.Context) {firstName := c.PostForm("first_name")familyName := c.PostForm("family_name")// Multipart formform, err := c.MultipartForm()if err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))return}files := form.File["file"]log.Println(form)for _, file := range files {log.Println(file.Filename)// Upload the file to specific dst.filename := filepath.Base(file.Filename)uploadPath := "./example/upload/" + filename// Upload the file to specific dst.if err := c.SaveUploadedFile(file, uploadPath); err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("upload file err: %s", err.Error()))return}}c.JSON(200, gin.H{"status": "posted","file lise": files,"file count": len(files),"first name": firstName,"family name": familyName,})}
server.go를 실행합니다.
12345678910111213141516171819$ go run example/server.go[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.- using env: export GIN_MODE=release- using code: gin.SetMode(gin.ReleaseMode)[GIN-debug] GET /uploadpage --> main.setupRouter.func1 (3 handlers)[GIN-debug] POST /upload --> main.uploadSingle (3 handlers)[GIN-debug] POST /multiupload --> main.uploadMultifile (3 handlers)[GIN-debug] GET /files/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)[GIN-debug] HEAD /files/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)[GIN-debug] Loaded HTML Templates (4):- index.html- note.html- uploadfile.html-[GIN-debug] Listening and serving HTTP on :8080
uploadpage를 열고 post 데이터와 파일을 선택합니다.
submit을 클릭하면 지정한 json 데이터가 리턴됩니다.
지정된 경로에는 파일이 업로드되어 있습니다.
12345678ll ./example/upload/total 2056drwxr-xr-x 6 tongchunkim staff 192B 2 28 18:28 .drwxr-xr-x 6 tongchunkim staff 192B 2 27 16:37 ..-rw-r--r-- 1 tongchunkim staff 34K 2 28 16:46 traffic_control.zip-rw-r--r-- 1 tongchunkim staff 321K 2 28 18:28 스크린샷 2019-02-28 오후 4.45.41.png-rw-r--r-- 1 tongchunkim staff 310K 2 28 18:28 스크린샷 2019-02-28 오후 4.46.50.png-rw-r--r-- 1 tongchunkim staff 356K 2 28 18:28 스크린샷 2019-02-28 오후 6.00.06.png
추가로 main() 함수에는 Static file 경로를 지정했습니다.
r.Static("/files", "./example/upload")
localhost:8080/files/ 하위 경로에 업로드한 파일을 추가하면 다운받을 수 있습니다.
http://localhost:8080/multiupload/traffic_control.zip
Gin을 이용한 파일 업로드였습니다.
'Golang > Gin' 카테고리의 다른 글
[swag] Gin에서 Swagger 사용하기 (0) | 2019.03.04 |
---|---|
Grouping routes (0) | 2019.03.04 |
Map as querystring or postform parameters (0) | 2019.02.27 |
Another example: query + post form (0) | 2019.02.15 |
Multipart/Urlencoded Form (1) | 2019.02.14 |