j'utilise Sockjs avec Go, mais lorsque le client javascript envoie json au serveur, il l'échappe et l'envoie en tant qu'octet []. j'essaie de comprendre comment analyser le json, afin que je puisse lire les données. mais je reçois cette erreur.
json: impossible de démêler la chaîne dans la valeur Go de type main.Msg
Comment puis-je réparer cela? html.UnescapeString () n'a aucun effet: /
val, err := session.ReadMessage()
if err != nil {
break
}
var msg Msg
err = json.Unmarshal(val, &msg)
fmt.Printf("%v", val)
fmt.Printf("%v", err)
type Msg struct {
Channel string
Name string
Msg string
}
//Output
"{\"channel\":\"buu\",\"name\":\"john\", \"msg\":\"doe\"}"
json: cannot unmarshal string into Go value of type main.Msg
Vous voudrez peut-être utiliser strconv.Unquote
sur votre chaîne JSON en premier :)
Voici un exemple , aimablement fourni par @gregghz:
package main
import (
"encoding/json"
"fmt"
"strconv"
)
type Msg struct {
Channel string
Name string
Msg string
}
func main() {
var msg Msg
var val []byte = []byte(`"{\"channel\":\"buu\",\"name\":\"john\", \"msg\":\"doe\"}"`)
s, _ := strconv.Unquote(string(val))
err := json.Unmarshal([]byte(s), &msg)
fmt.Println(s)
fmt.Println(err)
fmt.Println(msg.Channel, msg.Name, msg.Msg)
}
Vous devez corriger cela dans le code qui génère le JSON.
Quand il s'avère formaté comme ça, il est encodé JSON deux fois. Corrigez ce code qui effectue la génération afin qu'il ne se produise qu'une seule fois.
Voici du JavaScript qui montre ce qui se passe.
// Start with an object
var object = {"channel":"buu","name":"john", "msg":"doe"};
// serialize once
var json = JSON.stringify(object); // {"channel":"buu","name":"john","msg":"doe"}
// serialize twice
json = JSON.stringify(json); // "{\"channel\":\"buu\",\"name\":\"john\",\"msg\":\"doe\"}"
Comme l'a souligné Crazy Train, il semble que votre entrée soit doublement échappée, provoquant ainsi le problème. Une façon de résoudre ce problème est de vous assurer que la fonction session.ReadMessasge()
renvoie une sortie appropriée correctement échappée. Cependant, si ce n'est pas possible, vous pouvez toujours faire ce que x3ro a suggéré et utiliser la fonction golang strconv.Unquote
.
Voici un exemple de terrain de jeu en action:
Quelquefois, strconv.Unquote
ne fonctionne pas.
Voici un exemple qui montre le problème et ma solution. (Le lien du terrain de jeu: https://play.golang.org/p/Ap0cdBgiA05 )
Merci pour l'idée "encode deux fois" de @Crazy Train, je viens de la décoder deux fois ...
package main
import (
"encoding/json"
"fmt"
"strconv"
)
type Wrapper struct {
Data string
}
type Msg struct {
Photo string
}
func main() {
var wrapper Wrapper
var original = `"{\"photo\":\"https:\/\/www.abc.net\/v\/t1.0-1\/p320x320\/123.jpg\"}"`
_, err := strconv.Unquote(original)
fmt.Println(err)
var val []byte = []byte("{\"data\":"+original+"}")
fmt.Println(string(val))
err = json.Unmarshal([]byte(val), &wrapper)
fmt.Println(wrapper.Data)
var msg Msg
err = json.Unmarshal([]byte(wrapper.Data), &msg)
fmt.Println(msg.Photo)
}
Vous êtes tombé dans un piège infâme de chaîne d'échappement de JavaScript. Très souvent, les gens sont confrontés (comme moi) au même problème dans Go, lors de la sérialisation de la chaîne JSON avec json.Marshal, par exemple:
in := `{"firstName":"John","lastName":"Dow"}` bytes, err := json.Marshal(in)
json.Marshal échappe les guillemets doubles, produisant le même problème lorsque vous essayez de démarshal les octets dans struct.
Si vous avez rencontré le problème dans Go, consultez Comment sérialiser correctement la chaîne JSON dans Golang poste qui décrit le problème en détail avec une solution.
Les données affichées dans le problème sont stringifiées à certaines fins, dans certains cas, vous pouvez même avoir \ n dans votre chaîne représentant un saut de ligne dans votre json.
Comprenons la manière la plus simple de démarsaler/désérialiser ce type de données en utilisant l'exemple suivant:
La ligne suivante montre les données que vous obtenez de vos sources et que vous souhaitez dersérialiser
stringifiedData: = "{\ r\n \" a\": \" b\",\r\n \" c\": \" d\"\ r\n}"
Maintenant, supprimez d'abord toutes les nouvelles lignes
stringifiedData = strings.ReplaceAll (stringifiedData, "\ n", "")
Ensuite, supprimez toutes les citations supplémentaires présentes dans votre chaîne
stringifiedData = strings.ReplaceAll (stringifiedData, "\\" ","\"")
Convertissons maintenant la chaîne en un tableau d'octets
dataInBytes: = [] octet (stringifiedData)
Avant de faire unmarshal, définissons la structure de nos données
jsonObject: = & struct {
Une chaîne `json:" a "`
Chaîne C `json:" c "`
}
Maintenant, vous pouvez dersialiser vos valeurs dans jsonObject
json.Unmarshal (dataInBytes, jsonObject)}