Maison > développement back-end > Golang > le corps du texte

Comment décoder ce json imbriqué avec Golang ?

WBOY
Libérer: 2024-02-10 18:45:08
avant
986 Les gens l'ont consulté

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

Comment décoder le JSON imbriqué avec Golang est un défi auquel de nombreux développeurs sont confrontés lorsqu'ils traitent des structures de données complexes. Dans cet article, l'éditeur PHP Banana vous présentera en détail comment utiliser le package JSON dans Golang pour analyser et traiter les données JSON imbriquées. En étudiant le contenu de cet article, vous serez en mesure de gérer facilement diverses structures JSON complexes et d'obtenir une analyse et un traitement des données plus efficaces. Que vous soyez débutant ou développeur expérimenté, cet article vous fournira des conseils utiles et des exemples de code pour vous aider à résoudre le difficile problème du décodage JSON. Explorons la méthode de décodage du JSON imbriqué dans Golang !

Contenu de la question

J'essaie de décoder un json imbriqué dans le cadre d'une requête contenant un fichier et des données.

Les données ressemblent à ceci

{data: {"date_required":null}}
Copier après la connexion

Je n'ai pas inclus l'erreur complète au départ parce que j'ai oublié de la documenter.

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
Copier après la connexion

Je pense que cette erreur peut être causée par le fait que les données du formulaire ne sont pas JSON, mais je ne sais pas comment y remédier. Mon code Flutter semble envoyer du JSON valide. Le type de contenu est multipart/form-data Cela peut être à l'origine de l'erreur. Je pense que ce type de contenu est requis pour la partie de téléchargement de fichiers de mon code.

La requête vient de mon client Flutter, le code est le suivant :

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;
Copier après la connexion

Dans mon API go, je fais ça.

Modèle (édité en fonction des réponses ci-dessous) :

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

type FileRequiredDateData struct {
    Data FileRequiredDate `json:"data"`
}
Copier après la connexion

Code :

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
Copier après la connexion

httputil.DumpRequest -> Type de contenu : multipart/form-data

Edit : Sur la base de la réponse à cette question, j'ai modifié le code comme suit :

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)


----
Copier après la connexion

Cela me donne ce résultat :

2023/11/17 23:23:30 data
2023/11/17 23:23:30 file
Copier après la connexion

Éditeur :

J'ai résolu le problème actuel en utilisant decoder := json.NewDecoder(part) 而不是 decoder := json.NewDecoder(r.Body)

Maintenant, je reçois une erreur lors de l'obtention du fichier de formulaire . Il semble que je devrais utiliser la pièce d'une manière ou d'une autre, mais la pièce n'a pas de propriétés de fichier. Depuis que j'ai ajouté les données du formulaire à la requête en plusieurs parties, r.Body n'est plus disponible. Cela ressemble à un problème différent.

Solution de contournement

Bien que cela ne résolve pas le problème 404 (veuillez mettre à jour votre question avec le code du gestionnaire de requêtes), votre structure ne semble pas correspondre à ce que vous envoyez. Vous pouvez procéder comme suit pour résoudre ce problème :

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

type FileRequiredDateData struct {
    Data FileRequiredDate `json:"data"`
}
Copier après la connexion

Cela devrait décoder le corps de la requête comme prévu.

Pour 404, vous devez vérifier que le chemin et la méthode de la requête envoyés par le code client correspondent au chemin et à la méthode du gestionnaire de requêtes du serveur.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!