【发布时间】:2018-09-21 13:34:19
【问题描述】:
我在 Go 中编写了一个小的 REST api,我正在使用相同的函数返回一个带有状态代码和消息的 http.Response:
type apiResponse struct {
Status int `json:"status"`
Message string `json:"message"`
}
我将其编组为 json 字符串并使用 w.Write() 将其放入响应中。
API 具有三个端点,其中一个允许用户上传文件。两个工作得很好,我得到了我期望的回应。
上传端点返回一个带有Content-Length 的有效响应,它与我期望的消息相匹配,但是当我阅读它时(使用ioutil.ReadAll),它是空的!
我做错了什么?
这是读取正文的函数:
func readResponseContent(resp *http.Response) string {
defer resp.Body.Close()
fmt.Println(resp)
fmt.Println(resp.ContentLength)
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error in response: %s", err.Error())
os.Exit(1)
}
bodyString := string(bodyBytes)
return bodyString
}
这是处理程序:
func handleSubmission(w http.ResponseWriter, r *http.Request) {
var Buf bytes.Buffer
file, header, err := r.FormFile(audioUploadKey)
if err != nil {
log.Printf("Error uploading file: %s\n", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer file.Close()
jobID, _ := uuid.NewUUID()
_ = os.MkdirAll(path.Join(jobsPath, jobID.String()), 0750)
log.Printf("Received file %s\n", header.Filename)
io.Copy(&Buf, file)
fileOut, _ := os.Create(path.Join(jobsPath, jobID.String(),
Buf.WriteTo(fileOut)
Buf.Reset()
// submit
// DO STUFF with jobID
apiResp := apiResponse{Status:http.StatusCreated, Message:jobID.String()}
jsonResp, _ := json.Marshal(apiResp)
writeJSONResponse(w, jsonResp)
return}
【问题讨论】:
-
显示
writeJSONResponse的代码。 -
在将响应正文传递给
readResponseContent之前,您确定没有其他人正在读取响应正文? -
您使用下划线返回错误只是为了让您的代码更小吗?鉴于您的代码实际上 确实 在那里检查了两次错误,我怀疑不是。如果这些下划线出现在您的实际代码中,请停止忽略错误。我看到 99.9% 的 json 编组/解组失败的问题是因为人们忽略了他们的错误并错过了一个完美解释的错误返回值。
-
我只是用它们来缩短这里的功能。我正在检查一切是否符合预期(正确的文件、正确的副本、正确的 ID,...)。
-
writeJSONResponse 只需要一个
[]byte,将内容类型设置为 json 并写入字节