#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.
}