【问题标题】:Json decode always executing irrespective of the structure无论结构如何,Json decode 总是执行
【发布时间】:2022-01-12 18:10:17
【问题描述】:

请帮助我解决以下问题,无论 json 响应的类型如何,条件都会被执行。这是一个返回 json 的示例公共 url,如果响应符合结构,我们只需记录标题。然而,无论什么 json 响应即将到来,代码都在条件内(err ==nil)。如果我没记错的话,json 解码器应该检查响应的结构。

我的代码在下面完成

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

type response struct {
    UserID int    `json:"userId"`
    ID     int    `json:"id"`
    Title  string `json:"title"`
    Body   string `json:"body"`
}

func main() {
    resp, err := http.Get("https://jsonplaceholder.typicode.com/posts/1")
    if err != nil {
        log.Fatalln(err)
    }
    var actual response

    if err = json.NewDecoder(resp.Body).Decode(&actual); err == nil {
        fmt.Printf("anotherLink from docker container: %s", actual.Title)

    }

【问题讨论】:

  • 默认 json.Decoder 不关心结构是否不同,只关心匹配目标结构的字段是否可以解码。如果您希望它在遇到不在reponse 中的字段时失败,请使用DisallowUnknownFields。但是请注意, json.Decoder 不提供“fail-if-field-is-missing”配置。因此,如果您在 json 中收到 {},那么 json.Decoder 不会失败,而是您必须自己验证生成的 response

标签: json go


【解决方案1】:

默认情况下,没有对应结构字段的对象键会被忽略。使用DisallowUnknownFields 使解码器返回未知键的错误。

d := json.NewDecoder(resp.Body)
d.DisallowUnknownFields()
if err = d.Decode(&actual); err == nil {
    fmt.Printf("anotherLink from docker container: %s", actual.Title)

}

这种方法的问题是结构类型必须包含服务器发送的每个字段。如果服务器以后添加新字段,解码将失败。

如果未设置指定字段,更好的选择是拒绝响应。

if err = json.NewDecoder(resp.Body).Decode(&actual); err != nil || actual.UserID == "" {
    // Handle bad response.
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    相关资源
    最近更新 更多