Представление null в JSON


каков предпочтительный метод для возврата нулевых значений в JSON? Есть ли другие предпочтения для примитивов?

например, если мой объект на сервере имеет целое число с именем "myCount" без значения, наиболее правильным JSON для этого значения будет:

{}

или

{
    "myCount": null
}

или

{
    "myCount": 0
}

тот же вопрос для строк - если у меня есть нулевая строка "myString" на сервере, это лучший JSON:

{}

или

{
    "myString": null
}

или

{
    "myStrung": ""
}

или (Господи помоги мне)

{
    "myString": "null"
}

мне нравится Соглашение для коллекций, которые будут представлены в JSON как пустая коллекция http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html

пустой массив будет представлено:

{
    "myArray": []
}

редактировать резюме

аргумент 'личные предпочтения' кажется реалистичным, но коротким, поскольку сообщество будет потреблять большее количество разрозненных услуг/источников. Соглашения для структуры JSON помогут нормализовать потребление и повторное использование указанных услуг. Что касается установления стандарта, я бы предложил принять большинство конвенций Джексона с несколькими исключениями:

  • объекты предпочтительнее примитивов.
  • пустые коллекции являются предпочтительными по сравнению с нулем.
  • объекты без значения представлены как null.
  • примитивы возвращают свое значение.

если вы возвращаете объект JSON с главным образом нулевыми значениями, у вас может быть кандидат для рефакторинга в несколько служб.

{

    "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

}

вышеуказанный JSON был сгенерирован из следующего класса Java.

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:

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

7 ответов:

давайте оценим разбор каждого:

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

The tl; dr здесь:

JSON2 путь спецификация JSON указано null должны быть представлены. Но как всегда, это зависит от того, что ты делаешь-иногда "правильный" способ сделать это не всегда работает для вашей ситуации. Используйте свое суждение и сделать обоснованное решение.


JSON1 {}

это возвращает пустой объект. Там нет никаких данных, и это только скажет вам, что какой бы ключ вы ни искали (будь то myCount или что-то другое) типа undefined.


JSON2 {"myCount": null}

в этом случае myCount фактически определен, хотя его значение null. Это не то же самое, что и " нет undefined, а не null", и если бы вы тестировали для одного условия или другого, это могло бы преуспеть, тогда как JSON1 потерпел бы неудачу.

это окончательный способ представления null на спецификация JSON.


JSON3 {"myCount": 0}

в этом случае, myCount равен 0. Это не то же самое как null, а это не то же самое как false. Если ваш условный оператор вычисляет myCount > 0, тогда это может быть полезно иметь. Кроме того, если вы выполняете вычисления на основе значения здесь, 0 может быть полезно. Если вы пытаетесь проверить для null однако, это на самом деле не собирается работать вообще.


JSON4 {"myString": ""}

в этом случае, вы получаете пустую строку. Опять же, как и в JSON2, он определен, но он пуст. Вы можете проверить для if (obj.myString == "") но вы не могли проверить для null или undefined.


JSON5 {"myString": "null"}

это, вероятно, приведет вас в беду, потому что вы устанавливаете строка значение null; в этом случае obj.myString == "null", но это не== null.


JSON6 {"myArray": []}

это скажет вам, что Ваш массив myArray существует, но он пуст. Это полезно, если вы пытаетесь выполнить подсчет или оценка myArray. Например, скажем, вы хотели оценить количество фотографий, опубликованных пользователем-вы можете сделать myArray.length и он вернется 0: определено, но фотографии не опубликованы.

null не ноль. Это не ценность, per se: это значение вне домена переменной, указывающее на отсутствующие или неизвестные данные.

есть только один способ представления null в JSON. В соответствии со спецификациями (RFC 4627 и 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

enter image description here

есть только один способ представления null; С 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

то есть; если какой-либо из клиентов, которые используют ваше представление JSON, используют === оператор; это может быть проблемой для них.

никакой ценности

если вы хотите передать, что у вас есть объект, атрибут которого myCount не имеет значения:

{ "myCount": null }

нет атрибута / отсутствует атрибут

что делать, если вы передать, что у вас есть объект без атрибутов:

{}

клиентский код будет пытаться получить доступ к myCount и вам undefined; его там нет.

пустой набор

что делать, если вам передать, что у вас есть объект с атрибутом myCount это пустой список:

{ "myCount": [] }

Я хотел бы использовать null чтобы показать, что нет никакого значения для этого ключа. Например, используйте null чтобы представить, что" количество устройств в вашем домашнем хозяйстве подключается к интернету " неизвестно.

С другой стороны, использовать {} если этот ключ не применяется. Например, вы не должны показывать счетчик, даже если null, на вопрос "количество автомобилей, которые имеют активное подключение к интернету" задается кому-то, кто не владеет никакими автомобилями.

Я бы избегайте дефолта любого значения, если это значение по умолчанию не имеет смысла. В то время как вы можете решить использовать null чтобы не представлять никакого значения, конечно, никогда не используйте "null" чтобы сделать так.

Я бы выбрал "по умолчанию" для типа данных переменной (null для строк/объектов 0 для чисел), но действительно проверьте, какой код, который будет потреблять объект ожидает. Не забывайте, что иногда существует различие между null/по умолчанию и "нет".

проверить нулевой объект шаблона - иногда лучше передать какой-то специальный объект вместо null (т. е. [] массив вместо null для массивов или "" для строк).

Это личный и ситуативный выбор. Важно помнить, что пустая строка и число ноль концептуально отличаются от null.

в случае a count вы, вероятно, всегда хотите какое-то действительное число (если только count неизвестно или не определено), но в случае строк, Кто знает? Пустая строка может значит что-то в вашем приложении. Или, может быть, это не так. Это до вас, чтобы решить.

по словам JSON spec, самый внешний контейнер не должен быть словарем (или "объектом"), как подразумевается в большинстве комментариев выше. Это также может быть список или голое значение (т. е. строка, число, логическое или нулевое). Если вы хотите представить нулевое значение в JSON, вся строка JSON (за исключением кавычек, содержащих строку JSON) просто null. Никаких скобок, никаких скобок, никаких кавычек. Вы можете указать словарь, содержащий ключ с нулевым значением ({"key1":null}), или список с нулевым значением ([null]), но это не нулевые значения сами по себе - это правильные словари и списки. Точно так же пустой словарь ({}) или пустой список ([]) прекрасно, но не являются нулевыми.

В 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