将Marshall JSON Slice转换为有效的JSON。

huangapple go评论98阅读模式
英文:

Marshall JSON Slice to valid JSON

问题

我正在使用Golang构建一个REST API,但在尝试正确地编组Json Slice时遇到了一些问题。我已经苦思冥想了一段时间,甚至在查看了几个问题和答案以及网上的资料后仍然没有解决。

基本上,我有一个称为Redis的客户端,在调用-X GET /todo/之后返回一个todos的切片。

[{"content":"test6","id":"46"} {"content":"test5","id":"45"}] //[]string

现在,我想根据是否找到了todos来返回给定的Response,所以我有一个类似的Struct

type Response struct {
    Status string
    Data []string
}

然后,如果我找到了一些todos,我只需使用以下代码将其编组为json:

if(len(todos) > 0){
    res := SliceResponse{"Ok", todos}
    response, _ = json.Marshal(res)
}

为了去除响应中不必要的\,我使用bytes.Replace,如下所示:

response = bytes.Replace(response, []byte("\\"), []byte(""), -1)

最后,得到的结果是:

{
    "Status" : "Ok",
    "Data" : [
        "{\"content\":\"test6\",\"id\":\"46\"}",
        "{\"content\":\"test5\",\"id\":\"45\"}"
    ]
}

正如你所看到的,每个{之前和每个}之后的"都是错误的,除了第一个和最后一个之外。
而正确的JSON应该是:

{
    "Status": "Ok",
    "Data": [{
        "content": "test6",
        "id": "46"
    }, {
        "content": "test5",
        "id": "45"
    }]
}

我成功地通过找到它们的索引并将其删除以及使用正则表达式来去除它们,但我想知道是否有一种更简洁和更好的方法来实现这一点?

英文:

I'm building a REST API using Golang but I'm having some troubles trying to correctly Marshalling a Json Slice. I've been scratching my head for a while now, even after looking to several questions and answer and on the web.

Essentially, I have a Redis client that called after a call -X GET /todo/ spits up a slice of todos

[{"content":"test6","id":"46"} {"content":"test5","id":"45"}] //[]string

Now, I want to return a given Response based on the fact that I found todos or not, so I have a Struct like

type Response struct {
    Status string
    Data []string
}

Then, If I found some todos I just Marshal a json with

if(len(todos) > 0){
    res := SliceResponse{"Ok", todos}
	response, _ = json.Marshal(res)
}

And, In order to remove unnecessary \ inside the response, I use bytes.Replace like

response = bytes.Replace(response, []byte("\\"), []byte(""), -1)

Finally, getting

{
   "Status" : "Ok",
   "Data" : [
              "{"content":"test6","id":"46"}",
              "{"content":"test5","id":"45"}"
    ]
}

As you can see each " before each { and after each }, excluding the first and the last ones, are clearly wrong.
While the correct JSON would be

{
	"Status": "Ok",
	"Data": [{
		"content ": "test6",
		"id ": "46"
	}, {
		"content ": "test5",
		"id ": "45"
	}]
}

> I successfully managed to get them off by finding their index and trim them off and
> also with regex but I was wondering.

Is there a clean and better way to achieve that?

答案1

得分: 7

每当可能时,你应该从与你期望的 JSON 匹配的 Go 对象进行编组。我建议从 Redis 解析 JSON:

type Response struct {
    Status string
    Data   []*Info
}

type Info struct {
    Content string `json:"content"`
    ID      string `json:"id"`
}

func main() {
    r := &Response{Status: "OK"}
    for _, d := range data {
        info := &Info{}
        json.Unmarshal([]byte(d), info)
        // 处理错误
        r.Data = append(r.Data, info)
    }
    dat, _ := json.Marshal(r)
    fmt.Println(string(dat))
}

Playground 链接

英文:

Whenever possible you should marshal from go objects that match your desired json. I'd recommend parsing the json from redis:

type Response struct {
	Status string
	Data   []*Info
}

type Info struct {
	Content string `json:"content"`
	ID      string `json:"id"`
}

func main() {
	r := &Response{Status: "OK"}
	for _, d := range data {
		info := &Info{}
		json.Unmarshal([]byte(d), info)
		//handle error
		r.Data = append(r.Data, info)
	}
	dat, _ := json.Marshal(r)
	fmt.Println(string(dat))
}

Playground Link

huangapple
  • 本文由 发表于 2017年5月9日 04:42:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/43856948.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定