在Go(Gin)中返回没有转义字符的JSON响应。

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

Json response in Go(Gin) without escape characters

问题

我最近开始使用GIN来开发Go API。我的API从数据库中获取数据,其中一列包含整数,另一列包含JSON字符串。

由于JSON字符串是动态的,所以我无法使用结构体来解析它。我正在使用map[string]interface{}来解析JSON并对其进行修改,然后再使用json.Marshal将其解析回JSON。现在我将这个JSON字符串作为响应返回,但是得到了转义字符。我已经搜索了一些相关的内容,但是还没有找到解决方案。

以下是我正在使用的代码部分:

var interface_obj map[string]interface{}
json.Unmarshal([]byte(grants.Data), &interface_obj)
grants_map := interface_obj["role_grants"].(map[string]interface{})
jsonString, err := json.Marshal(grants_map)
jsonBody := string(jsonString)

然后,我在GIN框架中将这个JSON作为响应返回,代码如下:

c.JSON(http.StatusCreated, gin.H{"message": "Json retrieved successfully", "data": jsonBody})

但是我得到的输出是:

{
    "data": "[{\"action\":\"read\",\"resource\":\"project\"},{\"action\":\"all\",\"resource\":\"users\"},{\"action\":\"all\",\"resource\":\"roles\"},{\"action\":\"all\",\"resource\":\"project-settings\"},{\"action\":\"create\",\"resource\":\"single-entity-screening\"},{\"action\":\"read\",\"resource\":\"single-entity-screening\"},{\"action\":\"create\",\"resource\":\"multi-batch-screening\"},{\"action\":\"read\",\"resource\":\"multi-batch-screening\"},{\"action\":\"read\",\"resource\":\"workspace\"},{\"action\":\"allocate\",\"resource\":\"workspace\"},{\"action\":\"update\",\"resource\":\"workspace\"},{\"action\":\"read\",\"resource\":\"case\"},{\"action\":\"allocate\",\"resource\":\"case\"},{\"action\":\"review\",\"resource\":\"case\"},{\"action\":\"update\",\"resource\":\"case\"},{\"action\":\"read\",\"resource\":\"report\"},{\"action\":\"read\",\"resource\":\"audit-trail\"},{\"action\":\"read\",\"resource\":\"delivery\"}]",
    "message": "Grants retrieved successfully"
}

我在控制台上打印出来的结果看起来是正确的,但是在响应中却出现了问题。有没有办法使用一些标准的方法来解决这个问题?请指导一下,谢谢。

英文:

I have recently started working on Go APIs using GIN. My API is getting the data from DB with two columns where one column contains integer and other contains a json string.
The json string is dynamic and hence i cant use struct for that.
I am using map[string]interface{} to parse the json and modify it and then parse it back to json using json.Marshal. Now i am returning this json string as a response but getting escape characters. Have done some search regarding that, but didnt find any solution yet.
Here is the part of code that i am using

var interface_obj map[string]interface{}
json.Unmarshal([]byte(grants.Data), &interface_obj)
grants_map := interface_obj["role_grants"].(map[string]interface{})
jsonString, err := json.Marshal(grants_map)
jsonBody := string(jsonString)

After this, I am returning this JSON as response in GIN framework like this

c.JSON(http.StatusCreated, gin.H{"message": "Json retrieved successfully", "data": jsonBody})

But the output i am getting is

{
    "data": "[{\"action\":\"read\",\"resource\":\"project\"},{\"action\":\"all\",\"resource\":\"users\"},{\"action\":\"all\",\"resource\":\"roles\"},{\"action\":\"all\",\"resource\":\"project-settings\"},{\"action\":\"create\",\"resource\":\"single-entity-screening\"},{\"action\":\"read\",\"resource\":\"single-entity-screening\"},{\"action\":\"create\",\"resource\":\"multi-batch-screening\"},{\"action\":\"read\",\"resource\":\"multi-batch-screening\"},{\"action\":\"read\",\"resource\":\"workspace\"},{\"action\":\"allocate\",\"resource\":\"workspace\"},{\"action\":\"update\",\"resource\":\"workspace\"},{\"action\":\"read\",\"resource\":\"case\"},{\"action\":\"allocate\",\"resource\":\"case\"},{\"action\":\"review\",\"resource\":\"case\"},{\"action\":\"update\",\"resource\":\"case\"},{\"action\":\"read\",\"resource\":\"report\"},{\"action\":\"read\",\"resource\":\"audit-trail\"},{\"action\":\"read\",\"resource\":\"delivery\"}]",
    "message": "Grants retrieved successfully"
}

I printed it on my console and it looked fine there, but causing this issue on response.
Is there any way to resolve this using some standard way? Please guide
Thanks

答案1

得分: 2

你不需要执行json.Marshal(grants_map),只需直接将值传递给gin.H,让c.JSON进行编码,例如:

gin.H{... "data": grants_map}

而在某些情况下,如果你确实有原始的JSON数据,并且想将其作为其他尚未为JSON的数据的一部分发送,你可以将其包装成json.RawMessage,以避免"双重编码",例如:

gin.H{... "data": json.RawMessage(jsonBody)}
英文:

You don't need to do json.Marshal(grants_map), just pass the value directly to gin.H and let c.JSON do the encoding, i.e.

gin.H{... "data": grants_map}

And in cases where you truly have raw JSON data at hand that you want to send as part of other not-yet-JSON data, you can wrap it into json.RawMessage to avoid the "double-encoding", i.e.

gin.H{... "data": json.RawMessage(jsonBody)}

huangapple
  • 本文由 发表于 2022年8月23日 22:27:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/73460507.html
匿名

发表评论

匿名网友

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

确定