如何在Golang的RESTful API中返回未转义的Json数据

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

How to return Json data without escape string in RESTful api on Golang

问题

我用Golang编写了一个API。这个API接收来自其他服务的数据,然后以JSON字符串的形式响应给用户。以下是我遇到的问题。

type message struct {
    Data string `json:"data"`
}

func test(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    data := // 从其他API获取包含反斜杠的消息
    json.NewEncoder(w).Encode(message{Data: data})
}

如果从其他API接收到的数据中包含反斜杠,这个API将以双反斜杠的形式发送响应。

例如:

接收到的数据:
"asdasdasd\asdasdasd"

响应数据:
{"data": "asdasdasd\\asdasdasd"}

我已经尝试解决这个问题。以下是我得到的结果。如果我使用fmt.Println()在屏幕上打印输出,一切都正常。

只有当我尝试将这些输出发送到JSON字符串时才会出现问题。因此,有没有办法在不使用双反斜杠的情况下发送这些数据?

英文:

I have written an API with Golang. This API does receive data from other services then it responses to users in type of JSON string. Here is the problems I got.

type message struct {
	Data string `json:"data"`
}

func test(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    data := // Retrieve message that contain backslash
    json.NewEncoder(w).Encode(message{Data: data})
}

`
If there is a backslash in data that receive from other API. This API will send the response with double backslashes.

Example.

Received data:
"asdasdasd\asdasdasd"

Response data:
{"data": "asdasdasd\\asdasdasd"}

I have try to figure this out. Here what I got. All of this will be fine if I try to print out in the screen by using fmt.Println().

I only get problem when I try to send those out put in JSON string. Therefore, is there any way to send those data without double backslashes?

答案1

得分: 1

我之前几天问了几乎相同的问题,这里是那篇帖子。

基本上,你不希望你的数据是一个string,而是一个interface{}

type message struct {
    Data interface{} `json:"data"`
}

我认为这对你也适用。如果你想使用 RESTful 并返回不同类型的结构体,这绝对是正确的方法。

英文:

I asked pretty much the same question a couple days ago, here's the post.

Basically you don't want your Data to be a string but an interface{} instead.

type message struct {
    Data interface{} `json:"data"`
}

I think this may apply to you also. And if you want to go RESTFul and return different types of structs, this is definitely the way to go.

答案2

得分: 1

根据评论中的建议,json.RawMessage可以解决这个问题。

data := map[string]interface{}{}
data["date"] = json.RawMessage([]byte(`"\/Date(1590105600000)\/"`))

b := new(bytes.Buffer)
json.NewEncoder(b).Encode(data)

fmt.Println(b.String())
// {"date":"\/Date(1590105600000)\/"}
英文:

As suggested in the comments, json.RawMessage does the trick.

data := map[string]interface{}{}
data["date"] = json.RawMessage([]byte(`"\/Date(1590105600000)\/"`))

b := new(bytes.Buffer)
json.NewEncoder(b).Encode(data)

fmt.Println(b.String())
// {"date":"\/Date(1590105600000)\/"}

答案3

得分: 0

Golang的默认渲染会对JSON进行转义,但如果你想禁用它,你需要定义一个自定义的渲染器,像这样:

encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
encoder.Encode(data)
英文:

Golang default render will escape JSON, but if you want to disable it you need to define custom renderer like this:

encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
encoder.Encode(data)

答案4

得分: -1

你可以创建一个自定义方法,将双反斜杠替换为单个反斜杠。类似这样:

func JSONMarshal(v interface{}, backslashEscape bool) ([]byte, error) {
    b, err := json.Marshal(v)

    if backslashEscape {
        b = bytes.Replace(b, []byte(`\\`), []byte(`\`), -1)
    }
    return b, err
}

json/encoder 包还有一个 DisableHTMLEscaping 方法,如果设置为 true(默认为 false),它允许你转义 HTML 字符。

英文:

You can create a custom method and replace double backslashes with a single one.
Something like that:

func JSONMarshal(v interface{}, backslashEscape bool) ([]byte, error) {
    b, err := json.Marshal(v)

    if backslashEscape {
        b = bytes.Replace(b, []byte(`\\`), []byte(`\`), -1)
    }
    return b, err
}

The json/encoder packages has also DisableHTMLEscaping, if set to true, default is false, it allows you to escape HTML chars.

huangapple
  • 本文由 发表于 2017年8月28日 16:34:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/45914863.html
匿名

发表评论

匿名网友

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

确定