在使用golang中的ioutil读取时,将无效的null添加到HTTP响应JSON主体中。

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

Invalid null added to HTTP response JSON body when reading with ioutil in golang

问题

这个问题让我头疼不已。我甚至不确定标题是否完全正确,因为我很难将问题缩小到一个具体的部分。

我有两个应用程序通过REST相互通信。其中一个应用程序接受来自另一个应用程序的HTTP GET请求,并返回一些JSON数据。对于HTTP路由器,我使用的是Gorilla/mux。到目前为止还好。

我的第一个应用程序(我们称之为FooReader)通过HTTP GET调用我的第二个应用程序(我们称之为FooWriter):

req, err := http.NewRequest("GET", url, nil)
req.Header.Set("uuid", "my uuid")
req.Header.Set("api_token", "my token")
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
    ...
}
defer resp.Body.Close()

这个工作得很好。你可以看到我在头部发送了一些额外的内容,这就是为什么我没有使用http.Get()。(有更好的方法吗?)

现在FooWriter接收到该请求并进行处理:

...
var successJSON = "{\"foo\":\"bar\"}"
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.Write([]byte(successJSON))
w.WriteHeader(200)

if err := json.NewEncoder(w).Encode(err); err != nil {
    ...
}

回到FooReader,我现在接收来自FooWriter的响应并读取它(为了清晰起见,我再次添加了Do()调用):

resp, err := client.Do(req)
if err != nil {
    ...
}
defer resp.Body.Close()

fmt.Println("response Code:", resp.StatusCode)

body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1048576))
if err != nil {
    ...
}

fmt.Println("response Body:", string(body))

现在出现了奇怪的情况:当我像最后一行那样打印响应正文时,原始的JSON字符串中会添加一个额外的null

response Code: 200
response Body: {"foo":"bar"}null

我猜测在JSON解码之前有一些nil被添加进去了,但我就是找不到它。
另外,我猜测问题可能出在FooReader这一侧,因为我在应用程序的其他部分上在FooWriter这一侧使用了完全相同的代码,而那部分代码运行良好。

我有什么遗漏吗?非常感谢任何帮助!

英文:

So this one is driving me insane. I'm not even sure if the title is 100% correct because I'm having some trouble to narrow the issue down to one specific part.

I have two applications that talk to each other via REST. One accepts the HTTP GET request from the other app, and answers with some JSON. For the HTTP router I use Gorilla/mux btw. So far so good.

My first application (let's call it FooReader), is calling my second application (let's call it FooWriter) via HTTP GET:

req, err := http.NewRequest("GET", url, nil)
req.Header.Set("uuid", "my uuid")
req.Header.Set("api_token", "my token")
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
    ...
}
defer resp.Body.Close()

This works just fine. As you can see I'm sending some additional stuff in the header, that's why I'm not using http.Get(). (Is there a better way to do this?)

Now FooWriter receives that request and processes it:

...
var successJSON = "{\"foo\":\"bar\"}"
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.Write([]byte(successJSON))
w.WriteHeader(200)

if err := json.NewEncoder(w).Encode(err); err != nil {
    ...
}

Back in FooReader I now receive the response from FooWriter and read it (I've added the Do() call again for clarity):

resp, err := client.Do(req)
if err != nil {
    ...
}
defer resp.Body.Close()

fmt.Println("response Code:", resp.StatusCode)

body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1048576))
if err != nil {
    ...
}

fmt.Println("response Body:", string(body))

Now comes the weird part: When I print the response body like I do in the last line, there is an additional null added to the original JSON string:

response Code: 200
response Body: {"foo":"bar"}null

My guess is that there is some nil thrown in there before the JSON decoding, but I just can't find it.
Also I'm guessing that the issue has to be on the FooReader side, because I'm using the exact same code on FooWriter side on some other part of the application, which works fine.

Did I miss anything? Any help is much appreciated!

答案1

得分: 1

if err := json.NewEncoder(w).Encode(err) 当 err 为 nil 时打印 null。将 response 传递给 encode 并将 err 作为其一部分,这样只会打印一个 JSON 结构。

英文:

if err := json.NewEncoder(w).Encode(err) is printing null when err is nil. Pass response to encode and make err part of it so only one json structure is printed.

huangapple
  • 本文由 发表于 2016年3月28日 15:02:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/36257576.html
匿名

发表评论

匿名网友

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

确定