Null vertegenwoordigen in JSON

Wat is de voorkeursmethode voor het retourneren van null-waarden in JSON? Is er een andere voorkeur voor primitieven?

Als mijn object op de server bijvoorbeeld een geheel getal heeft met de naam “myCount” zonder waarde, is de meest correcte JSON voor die waarde:

{}

of

{
    "myCount": null
}

of

{
    "myCount": 0
}

Dezelfde vraag voor Strings – als ik een null-string “myString” op de server heb, is dit de beste JSON:

{}

of

{
    "myString": null
}

of

{
    "myString": ""
}

of (heer help me)

{
    "myString": "null"
}

Ik hou van de conventie dat collecties in de JSON worden weergegeven als een lege collectie http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html

Een lege array wordt weergegeven:

{
    "myArray": []
}

Samenvatting BEWERKEN

Het ‘persoonlijke voorkeur’-argument lijkt realistisch, maar is kortzichtig omdat we als gemeenschap een steeds groter aantal ongelijksoortige diensten/bronnen zullen consumeren. Conventies voor de JSON-structuur zouden het verbruik en het hergebruik van genoemde services helpen normaliseren. Wat betreft het vaststellen van een standaard, zou ik willen voorstellen om de meeste Jackson-conventies over te nemen, met een paar uitzonderingen:

  • Objecten hebben de voorkeur boven primitieven.
  • Lege verzamelingen hebben de voorkeur boven nul.
  • Objecten zonder waarde worden weergegeven als null.
  • Primitieven geven hun waarde terug.

Als u een JSON-object retourneert met voornamelijk null-waarden, heeft u mogelijk een kandidaat voor refactoring in meerdere services.

{
    "value1": null,
    "value2": null,
    "text1": null,
    "text2": "hello",
    "intValue": 0, //use primitive only if you are absolutely sure the answer is 0
    "myList": [],
    "myEmptyList": null, //NOT BEST PRACTICE - return [] instead
    "boolean1": null, //use primitive only if you are absolutely sure the answer is true/false
    "littleboolean": false
}

De bovenstaande JSON is gegenereerd op basis van de volgende Java-klasse.

package jackson;    
import java.util.ArrayList;
import java.util.List;    
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonApp {    
    public static class Data {    
        public Integer value1;    
        public Integer value2;
        public String text1;
        public String text2 = "hello";
        public int intValue;
        public List<Object> myList = new ArrayList<Object>();
        public List<Object> myEmptyList;
        public Boolean boolean1;
        public boolean littleboolean;   
   }
   public static void main(String[] args) throws Exception {
       ObjectMapper mapper = new ObjectMapper();
       System.out.println(mapper.writeValueAsString(new Data()));
   }
}

Maven-afhankelijkheid:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.3.0</version>
</dependency>

Antwoord 1, autoriteit 100%

Laten we de ontleding van elk evalueren:

http://jsfiddle.net/brandonscript/Y2dGv/

var json1 = '{}';
var json2 = '{"myCount": null}';
var json3 = '{"myCount": 0}';
var json4 = '{"myString": ""}';
var json5 = '{"myString": "null"}';
var json6 = '{"myArray": []}';
console.log(JSON.parse(json1)); // {}
console.log(JSON.parse(json2)); // {myCount: null}
console.log(JSON.parse(json3)); // {myCount: 0}
console.log(JSON.parse(json4)); // {myString: ""}
console.log(JSON.parse(json5)); // {myString: "null"}
console.log(JSON.parse(json6)); // {myArray: []}

De tl;drhier:

Het fragment in de json2variabele is de manier waarop de JSON-specificatieaangeeft nullmoet worden weergegeven. Maar zoals altijd hangt het af van wat je doet — soms werkt de “juiste” manier om het te doen niet altijd voor jouw situatie. Gebruik uw oordeel en neem een weloverwogen beslissing.


JSON1 {}

Dit retourneert een leeg object. Er zijn daar geen gegevens, en het zal je alleen vertellen dat welke sleutel je ook zoekt (of het nu myCountof iets anders is) van het type undefinedis.


JSON2 {"myCount": null}

In dit geval is myCountfeitelijk gedefinieerd, hoewel de waarde nullis. Dit is niethetzelfde als zowel “niet undefinedals niet null“, en als u op de ene of de andere aandoening testte, zou dit kunnen slagen terwijl JSON1 zou mislukken.

Dit is de definitieve manier om nullweer te geven volgens de JSON-specificatie.


JSON3 {"myCount": 0}

In dit geval is myCount 0. Dat is niet hetzelfde als null, en het is niet hetzelfde als false. Als uw voorwaardelijke instructie myCount > 0, dan is dit misschien de moeite waard om te hebben. Bovendien, als u berekeningen uitvoert op basis van de waarde hier, kan 0 handig zijn. Als je echter probeert te testen op null, gaat dit helemaal niet werken.


JSON4 {"myString": ""}

In dit geval krijg je een lege string. Nogmaals, net als bij JSON2 is het gedefinieerd, maar het is leeg. Je zou kunnen testen op if (obj.myString == "")maar je zou niet kunnen testen op nullof undefined.


JSON5 {"myString": "null"}

Hierdoor kom je waarschijnlijk in de problemen, omdat je de stringwaarde op null zet; in dit geval obj.myString == "null"maar het is niet== null.


JSON6 {"myArray": []}

Hiermee wordt u verteld dat uw array myArraybestaat, maar het is leeg. Dit is handig als u probeert een telling of evaluatie op te voeren op myArray. Zeg bijvoorbeeld dat je het aantal foto’s een gebruiker wilde evalueren – je zou kunnen doen myArray.lengthen het zou terugkeren 0: gedefinieerd, maar geen foto’s gemaakt.


Antwoord 2, Autoriteit 50%

nullis niet nul. Het is geen waarde, per se : het is een waarde buiten het domein van de variabele die vermiste of onbekende gegevens aangeeft.

Er is maar één manier om nullin JSON weer te geven. Per de specificaties (rfc 4627 en json.org ):

2.1. Waarden
Een JSON-waarde moet een object, array, nummer of string of een van
De volgende drie letterlijke namen:
 valse null waar


Antwoord 3, Autoriteit 8%

Er is slechts één manier om nullweer te geven; dat is met null.

console.log(null === null);   // true
console.log(null === true);   // false
console.log(null === false);  // false
console.log(null === 'null'); // false
console.log(null === "null"); // false
console.log(null === "");     // false
console.log(null === []);     // false
console.log(null === 0);      // false

Dat wil zeggen; Als een van de clients die uw JSON-representatie consumeren, gebruikt u de ===exploitant; het kan een probleem voor hen zijn.

Geen waarde

Als u wilt overbrengen dat u een object hebt waarvan het kenmerk myCountgeen waarde heeft:

{ "myCount": null }

geen kenmerk / ontbrekend kenmerk

Wat als u wilt overbrengen dat u een object heeft zonder attributen:

{}

Cliëntcode probeert toegang te krijgen tot myCounten krijgt undefined; het is er niet.

lege verzameling

Wat als u wilt overbrengen dat u een object heeft met een attribuut myCountdat een lege lijst is:

{ "myCount": [] }

Antwoord 4, autoriteit 3%

Ik zou nullgebruiken om aan te tonen dat er geen waarde is voor die specifieke sleutel. Gebruik bijvoorbeeld nullom aan te geven dat “het aantal apparaten in uw huishouden dat verbinding heeft met internet” onbekend is.

Gebruik daarentegen {}als die specifieke sleutel niet van toepassing is. U moet bijvoorbeeld geen telling laten zien, zelfs niet als null, op de vraag “aantal auto’s met actieve internetverbinding” wordt gesteld aan iemand die geen auto heeft.

Ik zou vermijden om een waarde in gebreke te stellen, tenzij die standaard zinvol is. Hoewel je kunt besluiten om nullte gebruiken om geen waarde weer te geven, mag je zeker nooit "null"gebruiken om dit te doen.


Antwoord 5, autoriteit 2%

Ik zou “standaard” kiezen voor het gegevenstype van de variabele (nullvoor tekenreeksen/objecten, 0voor getallen), maar controleer inderdaad welke code het object zal verbruiken verwacht. Vergeet niet dat er soms onderscheid is tussen null/default versus “niet aanwezig”.

Uitchecken NULL Objectpatroon – Soms is het beter om een ​​speciaal object door te geven in plaats van null(dwz []array in plaats van nullvoor arrays of ""voor strings).


Antwoord 6

Dit is een persoonlijke en situationele keuze. Het belangrijkste om te onthouden is dat de lege reeks en het nummer nul conceptueel verschillen van null.

In het geval van een countU wilt waarschijnlijk altijd een geldig nummer (tenzij de countonbekend of undefined is), maar in het geval van snaren, wie weet? De lege string kan betekenen iets in uw toepassing. Of misschien niet. Dat is aan jou om te beslissen.


Antwoord 7

Volgens de json spec , hoeft de buitenste container geen woordenboek (of ‘object te zijn ‘) Zoals impliciet in de meeste van de bovenstaande opmerkingen. Het kan ook een lijst zijn of een kale waarde (d.w.z. string, nummer, boolean of null). Als u een NULL-waarde in JSON wilt vertegenwoordigen, is de volledige JSON-string (exclusief de quotes met de JSON-string) eenvoudigweg null. Geen beugels, geen beugels, geen citaten. U kunt een woordenboek opgeven met een sleutel met een nulwaarde ({"key1":null}) of een lijst met een NULL-waarde ([null]), maar Dit zijn geen null-waarden zelf – ze zijn eigenlijk woordenboeken en lijsten. Evenzo zijn een leeg woordenboek ({}) of een lege lijst ([]) perfect, maar ook niet null.

in Python:

>>> print json.loads('{"key1":null}')
{u'key1': None}
>>> print json.loads('[null]')
[None]
>>> print json.loads('[]')
[]
>>> print json.loads('{}')
{}
>>> print json.loads('null')
None

Other episodes