首頁 > 後端開發 > Golang > 主體

如何用 Golang 解碼這個巢狀的 json?

WBOY
發布: 2024-02-10 18:45:08
轉載
980 人瀏覽過

如何用 Golang 解码这个嵌套的 json?

如何用Golang解碼巢狀的JSON,是許多開發者在處理複雜資料結構時所面臨的挑戰。在這篇文章中,php小編香蕉將為您詳細介紹如何使用Golang中的JSON套件來解析和處理巢狀的JSON資料。透過學習本文的內容,您將能夠輕鬆處理各種複雜的JSON結構,實現更有效率的資料解析和處理。無論您是初學者還是有一定經驗的開發者,本文都將為您提供有用的技巧和範例程式碼,幫助您解決JSON解碼的難題。讓我們一起來探索Golang中解碼嵌套JSON的方法吧!

問題內容

我正在嘗試將巢狀 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。內容類型是 multipart/form-data 這可能是導致錯誤的原因。我相信我的程式碼的文件上傳部分需要此內容類型。

請求來自我的 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 -> 內容類型:multipart/form-data

編輯:根據這個問題的答案,我編輯瞭如下程式碼:

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) 解決了當前問題

現在我在取得表單檔案時遇到錯誤。看來我應該以某種方式使用零件,但零件沒有文件屬性。自從我將表單資料新增至多部分請求後,r.Body 不再可用。這看起來像是不同的問題。

解決方法

雖然這不能解決 404 問題(請使用請求處理程序程式碼更新您的問題),但您的結構似乎與您發送的內容不符。您可以執行以下操作來解決此問題:

type FileRequiredDate struct {
    DateRequired pgtype.Date `json:"date_required"`
}

type FileRequiredDateData struct {
    Data FileRequiredDate `json:"data"`
}
登入後複製

這應該可以按預期解碼請求正文。

對於 404,您應該仔細檢查客戶端程式碼發送的請求路徑和方法是否與伺服器請求處理程序路徑和方法相符。

以上是如何用 Golang 解碼這個巢狀的 json?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!