Декодирование Json всегда выполняется независимо от структуры

#json #go

#json #Вперед

Вопрос:

Пожалуйста, помогите мне с приведенным ниже, как всегда, условие выполняется независимо от типа ответа json. Это пример общедоступного URL, возвращающего json, и мы просто регистрируем заголовок, если ответ соответствует структуре. Однако, какой бы ни был ответ 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(amp;actual); err == nil {
        fmt.Printf("anotherLink from docker container: %s", actual.Title)

    }
 

Комментарии:

1. json по умолчанию. Декодеру все равно, отличается ли структура, ему важно только, могут ли быть декодированы поля, соответствующие целевой структуре. Используйте DisallowUnknownFields , если вы хотите, чтобы он завершался сбоем в случае, если он обнаруживает поля, которых нет reponse . Обратите внимание, однако, что json. Декодер не предоставляет конфигурацию «сбой, если поле отсутствует». Итак, если вы получаете {} в json, то json. Декодер не выйдет из строя, вместо этого вы должны сами проверить полученный response результат.

Ответ №1:

По умолчанию ключи объекта, которые не имеют соответствующего поля структуры, игнорируются. Используйте DisallowUnknownFields, чтобы заставить декодер возвращать ошибку для неизвестных ключей.

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

}
 

Проблема с этим подходом заключается в том, что тип структуры должен включать каждое поле, отправленное сервером. Декодирование завершится ошибкой, если сервер добавит новое поле в будущем.

Лучшим вариантом является отклонение ответа, если указанные поля не заданы.

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