如何在响应体中分别设置错误代码和编组 JSON?

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

How to separately set error code along with marshalling json in response body?

问题

在我的应用程序中,当出现错误时,我会在响应体中编写一个JSON错误消息,但这会使响应代码变为200。我尝试分别执行以下操作:

json.NewEncoder(res).Encode(errorBody)
res.WriteHeader(http.StatusBadRequest)

但它仍然返回响应代码200,并显示警告说我进行了多次WriteHeader调用。我希望像这样使用:

http.Error(res,"这里是一些错误消息",http.StatusBadRequest)

但是,我希望错误消息以JSON格式而不是文本格式呈现。我应该怎么做?

英文:

In my application, when there is error I am writing a json error message on response body but this makes response code 200. I tried separately doing

json.NewEncoder(res).Encode(errorBody)
res.WriteHeader(http.StatusBadRequest)

But it still gives out response code 200 along with a warning that I am making multiple WriteHeader calls. I want to have something like

http.Error(res,"Some Error Message here",http.StatusBadRequest)

but instead of the error message in text format, I want it to be in JSON. What should I do?

答案1

得分: 1

你可以先写头部,然后再写主体。

res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.WriteHeader(http.StatusBadRequest)
if err = json.NewEncoder(res).Encode(err); err != nil {
    // 处理编码器错误
}

如果响应仍然是200,或者你收到了警告,那意味着你或者你使用的某些包在其他地方为你写入了头部。

更新:(回答评论中相关的问题)

json.NewEncoder(res).Encode(err)调用了resWrite方法,标准库net/http中的Write方法会自动将状态设置为200(如果尚未设置)。而WriteHeader的实现会检查状态是否已经设置,如果已经设置,则只会记录警告并退出,不会覆盖它。

因此,如果你想控制状态,你需要在写入响应之前调用WriteHeader,无论是使用编码器写入JSON还是自己调用res.Write

英文:

You can write the header first and then the body.

res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.WriteHeader(http.StatusBadRequest)
if err = json.NewEncoder(res).Encode(err); err != nil {
    // handle encoder error
}

And if the response is still 200 and/or you're getting the warning, that means that you or some of the packages you use are writing the header for you in some other place.

Update: (to answer relevant question from comment)

json.NewEncoder(res).Encode(err) calls the Write method on res, and the implementation of Write from the standard net/http package automatically sets the status to 200 if it's not already set. And the implementation of WriteHeader checks whether status is already set or not and if it is, it just logs the warning and bails, without overwriting it.

So if you wan't to control the status you need to call WriteHeader before your write to the response whether you're writing json with the encoder or calling res.Write yourself.

答案2

得分: 0

json格式仍然是纯文本。首先将json.Marshal的errorBody转换为字符串。

body, err := json.Marshal(errBody)
if err != nil{
    // todo
}
http.Error(res, string(body), http.StatusBadRequest)
英文:

json format is still plain text. json.Marshal errorBody to string first.

body, err := json.Marshal(errBody)
if err != nil{
    // todo
}
http.Error(res, string(body), http.StatusBadRequest)

huangapple
  • 本文由 发表于 2017年4月12日 15:06:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/43362621.html
匿名

发表评论

匿名网友

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

确定