如何在 Go 中解组转义的 JSON 字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16846553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to unmarshal an escaped JSON string in Go?
提问by Robin Westerlundh
am using Sockjs with Go, but when the javascript client send json to the server it escapes it, and send's it as a []byte. i'm trying to figure out how to parse the json, so that i can read the data. but i get this error.
我在 Go 中使用 Sockjs,但是当 javascript 客户端将 json 发送到服务器时,它会对其进行转义,并将其作为 [] 字节发送。我想弄清楚如何解析 json,以便我可以读取数据。但我收到这个错误。
json: cannot unmarshal string into Go value of type main.Msg
json:无法将字符串解组为 main.Msg 类型的 Go 值
How can i fix this? html.UnescapeString() have no effect :/
我怎样才能解决这个问题?html.UnescapeString() 没有效果:/
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
回答by fresskoma
You might want to use strconv.Unquoteon your JSON string first :)
您可能想先strconv.Unquote在 JSON 字符串上使用:)
Here's an example, kindly provided by @gregghz:
这是一个示例,由@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)
}
回答by Robin Westerlundh
You need to fix this in the code that is generating the JSON.
您需要在生成 JSON 的代码中修复此问题。
When it turns out formatted like that, it is being JSON encoded twice. Fix that code that is doing the generating so that it only happens once.
当结果是这样的格式时,它被 JSON 编码了两次。修复正在生成的代码,使其只发生一次。
Here's some JavaScript that shows what's going on.
这是一些显示正在发生的事情的 JavaScript。
// 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\"}"
回答by noj
As Crazy Train pointed out, it appears that your input is doubly escaped, thus causing the issue. One way to fix this is to make sure that the function session.ReadMessasge()returns proper output that is escaped appropriately. However, if that's not possible, you can always do what x3ro suggested and use the golang function strconv.Unquote.
正如 Crazy Train 指出的那样,您的输入似乎被双重转义,从而导致了问题。解决此问题的一种方法是确保该函数session.ReadMessasge()返回正确转义的正确输出。但是,如果这是不可能的,您始终可以按照 x3ro 的建议进行操作并使用 golang 函数strconv.Unquote。
Here's a playground example of it in action:
这是它在行动中的一个操场示例:
回答by semicircle21
Sometimes, strconv.Unquotedoesn't work.
有时,strconv.Unquote不起作用。
Heres an example shows the problem and my solution. (The playground link: https://play.golang.org/p/Ap0cdBgiA05)
Heres一个例子显示了问题和我的解决方案。(游乐场链接:https: //play.golang.org/p/Ap0cdBgiA05)
Thanks for @Crazy Train's "encodes twice" idea, I just decoded it twice ...
感谢@Crazy Train 的“编码两次”的想法,我只解码了两次......
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)
}
回答by Avinash Dhinwa
The data shown in the problem is stringified for some purposes, in some cases you can even have \nin your string representing break of line in your json.
问题中显示的数据出于某些目的进行了字符串化,在某些情况下,您甚至可以在字符串中使用\n来表示 json 中的换行符。
Let's understand the easiest way to unmarshal/deserialize this kind of data using the following example:
让我们使用以下示例了解解组/反序列化此类数据的最简单方法:
Next line shows the data you get from your sources and want to derserialize
stringifiedData := "{\r\n \"a\": \"b\",\r\n \"c\": \"d\"\r\n}"
Now, remove all new lines first
stringifiedData = strings.ReplaceAll(stringifiedData, "\n", "")
Then remove all the extra quotes that are present in your string
stringifiedData = strings.ReplaceAll(stringifiedData, "\\"", "\"")
Let's now convert the string into a byte array
dataInBytes := []byte(stringifiedData)
Before doing unmarshal, let's define structure of our data
jsonObject := &struct{
A string `json:"a"`
C string `json:"c"`
}Now, you can dersialize your values into jsonObject
json.Unmarshal(dataInBytes, jsonObject)}
下一行显示您从来源获得并想要反序列化的数据
stringifiedData := "{\r\n \"a\": \"b\",\r\n \"c\": \"d\"\r\n}"
现在,首先删除所有新行
stringifiedData = strings.ReplaceAll(stringifiedData, "\n", "")
然后删除字符串中存在的所有额外引号
stringifiedData = strings.ReplaceAll(stringifiedData, "\\"", "\"")
现在让我们将字符串转换为字节数组
dataInBytes := []byte(stringifiedData)
在解组之前,让我们定义数据的结构
jsonObject := &struct{
一个字符串 `json:"a"`
C 字符串 `json:"c"`
}现在,您可以将值反序列化为 jsonObject
json.Unmarshal(dataInBytes, jsonObject)}
回答by upitau
You got into infamous escaped stringpitfall from JavaScript. Quite often people face (as I did) the same issue in Go, when serializing JSON string with json.Marshal, e.g.:
你从 JavaScript 中陷入了臭名昭著的转义字符串陷阱。当使用 json.Marshal 序列化 JSON 字符串时,人们经常在 Go 中遇到(就像我一样)同样的问题,例如:
in := `{"firstName":"John","lastName":"Dow"}`
bytes, err := json.Marshal(in)
in := `{"firstName":"John","lastName":"Dow"}`
bytes, err := json.Marshal(in)
json.Marshal escapes double quotes, producing the same issue when you try to unmarshal bytes into struct.
json.Marshal 转义双引号,当您尝试将字节解组到结构中时会产生相同的问题。
If you faced the issue in Go, have a look at How To Correctly Serialize JSON String In Golangpost which describes the issue in details with solution to it.
如果您在 Go 中遇到此问题,请查看How To Correctly Serialize JSON String In Golang帖子,其中详细描述了该问题及其解决方案。

