我正在try 将嵌套的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.
该请求来self 的Ffltter客户端,代码如下:
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
-&>内容类型:多部分/表单数据
编辑:按照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.Body不再可用,因为我向多部分请求中添加了表单数据.这看起来是一个不同的问题.