Représentation de null dans JSON

Quelle est la méthode préférée pour renvoyer des valeurs null dans JSON? Y a-t-il une préférence différente pour les primitives?

Par exemple, si mon objet sur le serveur a un entier appelé "myCount" sans valeur, le JSON le plus correct pour cette valeur serait:

{}

Ou

{
    "myCount": null
}

Ou

{
    "myCount": 0
}

Même question pour les chaînes-si j'ai une chaîne nulle "myString" sur le serveur, est le meilleur JSON:

{}

Ou

{
    "myString": null
}

Ou

{
    "myStrung": ""
}

Ou (seigneur aide-moi)

{
    "myString": "null"
}

J'aime que la convention pour les collections soit représentée dans le JSON comme une collection vide http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html

Un tableau vide serait représenté:

{
    "myArray": []
}

Modifier le résumé

L'argument de la "préférence personnelle" semble réaliste, mais court en ce sens qu'une communauté consommera un plus grand nombre de services/sources disparates. Les Conventions pour la structure JSON aideraient à normaliser la consommation et la réutilisation desdits services. En ce qui concerne l'établissement d'une norme, je suggère d'adopter la plupart des conventions de Jackson à quelques exceptions près:

  • les objets sont préférés aux primitives.
  • les collections vides sont préférées à null.
  • les objets sans valeur sont représentés par null.
  • les Primitives renvoient leur valeur.

Si vous renvoyez un objet JSON avec principalement null valeurs, vous pouvez avoir un candidat pour le refactoring dans plusieurs 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

}

Le JSON ci-dessus a été généré à partir de la classe Java suivante.

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()));
    }
}

Dépendance Maven:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.3.0</version>
</dependency>
252
demandé sur austin 2014-01-14 22:19:47

7 réponses

Évaluons l'analyse de chacun:

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: []}

Le tl;dr ici:

JSON2 {[42] } est la façon dont la spécification JSON indique que null doit être représenté. Mais comme toujours, cela dépend de ce que vous faites-parfois la "bonne" façon de le faire ne fonctionne pas toujours pour votre situation. Faites preuve de jugement et prenez une décision éclairée.


JSON1 {}

Renvoie un objet vide. Il n'y a pas de données là-bas, et cela va seulement vous dire que quelle que soit la clé que vous cherchez (que ce soit myCount ou autre chose) est de type undefined.


JSON2 {"myCount": null}

Dans ce cas, myCount est réellement défini, bien que sa valeur soit null. C'est pas la même chose que les deux " pas undefined et pas null", et si vous testiez une condition ou l'autre, cela pourrait réussir alors que JSON1 le ferait échouer.

C'est la façon définitive de représenter null par la spécification JSON.


JSON3 {"myCount": 0}

Dans ce cas, myCount vaut 0. Ce n'est pas le même que null, et ce n'est pas le même que false. Si votre instruction conditionnelle évalue myCount > 0, cela pourrait en valoir la peine. De plus, si vous exécutez des calculs basés sur la valeur ici, 0 pourrait être utile. Si vous essayez de tester pour null cependant, cela ne va pas fonctionner à tout.


JSON4 {"myString": ""}

Dans ce cas, vous obtenez une chaîne vide. Encore une fois, comme avec JSON2, il est défini, mais il est vide. Vous pouvez le tester pour if (obj.myString == ""), mais vous ne pourrais pas tester pour null ou undefined.


JSON5 {"myString": "null"}

Cela va probablement vous causer des problèmes, car vous définissez la valeurstring sur null; dans ce cas, obj.myString == "null" mais ce n'est pas == null.


JSON6 {"myArray": []}

Cela vous dira que votre tableau myArray existe, mais il est vide. Ceci est utile si vous essayez d'effectuer un comptage ou une évaluation sur myArray. Par exemple, disons que vous vouliez évaluer le nombre de photos publiées par un utilisateur - vous pourriez faire myArray.length et il retournerait 0: défini, mais aucune photo postée.

227
répondu brandonscript 2018-05-28 23:15:14

null n'est pas nul. Ce n'est pas une valeur, soi: c'est une valeur en dehors du domaine de la variable indiquant manquantes ou inconnues de données.

Il N'y a qu'une seule façon de représenter null dans JSON. Par les spécifications (RFC 4627 et json.org):

2.1.  Values

A JSON value MUST be an object, array, number, or string, or one of
the following three literal names:

  false null true

entrez la description de l'image ici

170
répondu Nicholas Carey 2015-03-31 17:18:38

Il n'y a qu'une façon de représenter null, c'est avec 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

C'est-à-dire, si l'un des clients qui consomment votre représentation JSON d'utiliser le === opérateur; il pourrait être un problème pour eux.

Aucune valeur

Si vous voulez transmettre que vous avez un objet dont les attributs myCount n'a pas de valeur:

{ "myCount": null }

Aucun attribut / attribut manquant

Que faire si vous transmettez que vous avez un objet sans attributs:

{}

Client le code va essayer d'accéder à myCount et obtenir undefined; ce n'est pas là.

Collection vide

Que faire si vous transmettez que vous avez un objet avec un attribut myCount qui est une liste vide:

{ "myCount": [] }
15
répondu dnozay 2015-12-18 17:35:35

J'utiliserais null pour montrer qu'il n'y a pas de valeur pour cette clé particulière. Par exemple, utilisez null pour représenter que "le nombre d'appareils dans votre ménage se connecte à internet" est inconnu.

D'autre part, utiliser {} si cette clé n'est pas applicable. Par exemple, vous ne devriez pas montrer un compte, même si null, à la question "nombre de voitures qui ont une connexion Internet active" est demandé à quelqu'un qui ne possède pas de voitures.

J'éviterais toute valeur par défaut sauf si cette valeur par défaut est logique. Bien que vous puissiez décider d'utiliser null pour ne représenter aucune valeur, n'utilisez certainement jamais "null" pour le faire.

12
répondu marcoseu 2018-08-15 15:29:46

Je choisirais "default" pour le type de variable de données (null pour les chaînes / objets, 0 pour les nombres), mais en effet vérifier quel code qui va consommer l'objet attend. N'oubliez pas qu'il y a parfois une distinction entre null / default et "non présent".

Découvrez objet null modèle - parfois, il vaut mieux passer à quelque objet spécial au lieu de null (c - [] tableau au lieu de null pour tableaux ou "" pour les chaînes).

6
répondu Alexei Levenkov 2014-01-14 18:28:50

C'est un choix personnel et situationnel. La chose importante à retenir est que la chaîne vide et le nombre zéro sont conceptuellement distincts de null.

Dans le cas d'un count vous voulez probablement toujours un nombre valide (sauf si le {[1] } est inconnu ou indéfini), mais dans le cas des chaînes, qui sait? La chaîne vide pourrait signifier quelque chose dans votre application. Ou peut-être qu'il ne l'est pas. C'est à vous de décider.

2
répondu Wayne Burkett 2014-01-14 18:29:32

Selon la spécification JSON , le conteneur le plus externe ne doit pas nécessairement être un dictionnaire (ou un 'objet') comme indiqué dans la plupart des commentaires ci-dessus. Il peut également s'agir d'une liste ou d'une valeur nue (c'est-à-dire chaîne, Nombre, booléen ou null). Si vous voulez représenter une valeur null dans JSON, la chaîne JSON entière (à l'exclusion des guillemets contenant la chaîne JSON) est simplement null. Pas d'accolades, pas de parenthèses, pas de guillemets. Vous pouvez spécifier un dictionnaire contenant une clé avec une valeur null ({"key1":null}), ou une liste avec les une valeur nulle ([null]), mais ce ne sont pas des valeurs nulles elles-mêmes - ce sont des dictionnaires et des listes appropriés. De même, un dictionnaire vide ({}) ou une liste vide ([]) sont parfaitement corrects, mais ne sont pas non plus nuls.

En 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
0
répondu iggie 2018-08-10 20:31:40