Ce face encoding/json.Decoder.DisallowUnknownFields
Implicit, cheile JSON fără câmp corespondent sunt ignorate în tăcere. Asta ascunde greșeli: un client trimite "emial" în loc de "email", iar câmpul rămâne gol fără nicio eroare. După dec.DisallowUnknownFields(), astfel de chei produc eroarea json: unknown field "emial".
Se apelează o singură dată, înainte de Decode, și se aplică doar când ținta este o structură. Este potrivit pentru API-uri stricte și fișiere de configurare; pentru date de la servicii externe, care pot adăuga câmpuri noi oricând, lasă comportamentul implicit.
Ce returnează
Nimic; schimbă comportamentul apelurilor Decode următoare.
Exemple
Exemplul 1: Greșeală de scriere prinsă
package main
import (
"encoding/json"
"fmt"
"strings"
)
type Config struct {
Port int `json:"port"`
Email string `json:"email"`
}
func citeste(text string, strict bool) {
dec := json.NewDecoder(strings.NewReader(text))
if strict {
dec.DisallowUnknownFields()
}
var c Config
err := dec.Decode(&c)
fmt.Printf("strict=%-5v %+v eroare: %v\n", strict, c, err)
}
func main() {
text := `{"port": 8080, "emial": "admin@example.ro"}`
citeste(text, false)
citeste(text, true)
}
Rezultat
strict=false {Port:8080 Email:} eroare: <nil>
strict=true {Port:8080 Email:} eroare: json: unknown field "emial"
Exemplul 2: Validare strictă pentru un API
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
)
type Transfer struct {
Catre string `json:"catre"`
Suma float64 `json:"suma"`
}
func transfer(w http.ResponseWriter, r *http.Request) {
dec := json.NewDecoder(r.Body)
dec.DisallowUnknownFields()
var t Transfer
if err := dec.Decode(&t); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Fprintf(w, "transfer de %.2f lei către %s", t.Suma, t.Catre)
}
func main() {
for _, corp := range []string{`{"catre":"RO49AAAA1B31007593840000","suma":250}`, `{"catre":"RO49AAAA1B31007593840000","suma":250,"comision":0}`} {
rec := httptest.NewRecorder()
transfer(rec, httptest.NewRequest("POST", "/transfer", strings.NewReader(corp)))
fmt.Println(rec.Code, strings.TrimSpace(rec.Body.String()))
}
}
Rezultat
200 transfer de 250.00 lei către RO49AAAA1B31007593840000
400 json: unknown field "comision"
Greșeli frecvente
- Apelezi
DisallowUnknownFieldsdupăDecode: primul obiect a fost deja citit fără verificare. - Te aștepți să funcționeze cu
json.Unmarshal: opțiunea există doar peDecoder. Pentru date în memorie foloseștejson.NewDecoder(bytes.NewReader(date)).
Comenzi înrudite
encoding/json.NewDecoder: Creează un Decoder care citește JSON dintr-un io.Reader (corpul unei cereri, un fișier); Decode citește o valoare.encoding/json.Unmarshal: Citește JSON și completează o valoare Go (structură, map, slice) dată prin pointer; potrivește cheile după etichetele json.encoding/json.Decoder.More: Spune dacă mai urmează un element în lista sau obiectul citit; cu Token permite citirea element cu element a unei liste mari.