我正在尝试将嵌套的json作为包含文件和数据的请求的一部分进行解码。
数据是这样的
{data: {"date_required":null}}
字符串
我最初没有包括完整的错误,因为我忘记了记录它。
2023/11/17 23:40:35 error in decoding request body data
2023/11/17 23:40:35 invalid character '.' looking for beginning of value
型
我相信这个错误可能是由于表单数据不是JSON,但不知道如何修复它。我的Flutter代码看起来像它发送了有效的JSON。Content-Type是multipart/form-data
,这可能是导致错误的原因。我相信我的代码的文件上传部分需要此Content-Type。
请求来自我的Flutter客户端,代码如下:
final multipartFile =
http.MultipartFile.fromBytes('file', bytes, filename: file?.name);
final request = http.MultipartRequest('POST', Uri.parse(user.fileUrl));
request.files.add(multipartFile);
request.headers.addAll(headers);
String dateRequiredStr = dateRequired != null
? jsonEncode({'date_required': dateRequired})
: jsonEncode({'date_required': null});
request.fields['data'] = dateRequiredStr;
型
在我的go API中,我正在执行此操作。
模型(根据下面的答案编辑):
type FileRequiredDate struct {
DateRequired pgtype.Date `json:"date_required"`
}
type FileRequiredDateData struct {
Data FileRequiredDate `json:"data"`
}
型
验证码:
func (rs *appResource) uploadTranscriptAudioFile(w http.ResponseWriter, r *http.Request) {
start := time.Now()
const maxUploadSize = 500 * 1024 * 1024 // 500 Mb
var requiredByDate FileRequiredDateData
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&requiredByDate)
if err != nil {
log.Println("error in decoding request body data")
log.Println(err.Error())
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
file, handler, err := r.FormFile("file")
if err != nil {
log.Println(err)
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
defer file.Close()
fileSize := handler.Size
if fileSize > maxUploadSize {
http.Error(w, "FILE_TOO_BIG", http.StatusBadRequest)
return
}
fileName := handler.Filename
型httputil.DumpRequest
-> Content-Type:multipart/form-data
编辑:根据this question的答案,我编辑了如下代码:
mr, err := r.MultipartReader()
if err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
for {
part, err := mr.NextPart()
// This is OK, no more parts
if err == io.EOF {
break
}
// Some error
if err != nil {
log.Println("multipart reader other error")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
log.Println(part.FormName())
if part.FormName() == "data" {
log.Println("multipart reader found multipart form name data")
decoder := json.NewDecoder(r.Body)
err = decoder.Decode(&requiredByDate)
if err != nil {
log.Println("error in decoding request body data")
log.Println(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
}
if part.FormName() == "file" {
file, handler, err := r.FormFile("file") <-- error here
if err != nil {
log.Println("error getting form file")
log.Println(err.Error())
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusInternalServerError)
return
}
defer file.Close()
guid := xid.New()
userId := getUserFromJWT(r)
user, err := getUser(rs, int64(userId))
if err != nil {
log.Println("user not found")
log.Println(err.Error())
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
err = uploadToMinio(rs, file, fileSize, fileName, guid.String(), userId)
----
型
这给了我这个输出:
2023/11/17 23:23:30 data
2023/11/17 23:23:30 file
型
编辑:
我通过使用decoder := json.NewDecoder(part)
而不是decoder := json.NewDecoder(r.Body)
修复了即时问题
现在我得到了error getting form file
。看起来我应该以某种方式使用part,但是part. r没有文件属性。由于我将表单数据添加到multipart请求中,因此Body不再可用。这看起来像是一个不同的问题。
1条答案
按热度按时间6gpjuf901#
虽然这不会解决404问题(请用请求处理程序代码更新您的问题),但您的结构体似乎与您发送的内容不匹配。您可以执行以下操作来解决此问题:
字符串
这应该会按预期解码请求正文。
对于404,您应该仔细检查客户端代码发送的请求路径和方法是否与服务器请求处理程序路径和方法匹配。