如何在Gin中编写一个GET端点,允许用户以JSON格式下载文件和元数据?

huangapple go评论87阅读模式
英文:

How to write a GET endpoint in Gin that lets the user download a file + metadata in json format?

问题

我已经创建了一个允许用户上传以JSON格式存储文件和元数据的端点,但是我在创建一个GET端点时遇到了一些问题,该端点允许用户在一次调用中下载文件和元数据。

我编写了下面的代码,它返回了JSON元数据+文件,但是JSON被添加到文件的开头,而不是作为一个单独的对象:

jsonData, err := json.Marshal(metadata)
// 设置响应头
c.Header("Content-Disposition", "attachment; filename=file.md")
c.Header("Content-Type", "application/octet-stream")

// 将文件内容和JSON数据写入响应体
c.Writer.Write(jsonData)
c.Writer.Write(file)

我该如何解决这个问题?

英文:

I have created an endpoint that allows users to upload a file + metadata in json format and I store them but I have some problems creating a GET endpoint that allows a user to download the file and metadata in json format in one call.

I wrote below code that returns the json metadata + file BUT the json is added at the beginning of the file and not as a separate object:

jsonData, err := json.Marshal(metadata)
// Set the response headers
c.Header("Content-Disposition", "attachment; filename=file.md")
c.Header("Content-Type", "application/octet-stream")

// Write the file contents and JSON data to the response body
c.Writer.Write(jsonData)
c.Writer.Write(file)

How can I solve this issue?

答案1

得分: 0

使用https://stackoverflow.com/users/5027489/whitesword的提示,我重写了代码以使用multipart/form-data,并解决了问题:

		// 设置响应头
		c.Header("Content-Disposition", "attachment; filename=file.md")
		c.Header("Content-Type", "multipart/form-data")

		// 创建一个多部分响应写入器
		writer := multipart.NewWriter(c.Writer)
		defer writer.Close()

		// 将文件添加到响应中
		fileWriter, err := writer.CreateFormFile("file", "file.md")
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "无法创建表单文件"})
			return
		}
		fileWriter.Write(file)

		// 将JSON数据添加到响应中
		jsonWriter, err := writer.CreateFormField("metadata")
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "无法创建表单字段"})
			return
		}
		jsonWriter.Write(jsonData)

		// 完成多部分响应
		c.Writer.Header().Set("Content-Type", writer.FormDataContentType())

		// 返回响应
		c.Writer.WriteHeader(http.StatusOK)
英文:

Using the https://stackoverflow.com/users/5027489/whitesword hint I rewrite my code to use multipart/form-data and that solved the problem:

		// Set the response headers
		c.Header("Content-Disposition", "attachment; filename=file.md")
		c.Header("Content-Type", "multipart/form-data")

		// Create a multipart response writer
		writer := multipart.NewWriter(c.Writer)
		defer writer.Close()

		// Add the file to the response
		fileWriter, err := writer.CreateFormFile("file", "file.md")
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create form file"})
			return
		}
		fileWriter.Write(file)

		// Add the JSON data to the response
		jsonWriter, err := writer.CreateFormField("metadata")
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create form field"})
			return
		}
		jsonWriter.Write(jsonData)

		// Complete the multipart response
		c.Writer.Header().Set("Content-Type", writer.FormDataContentType())

		// Return the response
		c.Writer.WriteHeader(http.StatusOK)

huangapple
  • 本文由 发表于 2023年4月14日 15:48:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76012709.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定