Представление нулевого значения в JSON

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

Например, если мой объект на сервере имеет Integer с именем «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": [] } 

Сводка EDIT

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

  • Объекты предпочтительнее примитивов.
  • Пустые коллекции предпочтительнее нуля.
  • Объекты без значения представлены как 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-classа.

 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 myList = new ArrayList(); public List 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:

  com.fasterxml.jackson.core jackson-core 2.3.0  

Давайте оценим parsing каждого из них:

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

Здесь 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 не равно нулю. Это не значение, как таковое : это значение вне домена переменной, указывающее отсутствие или неизвестные данные.

Существует только один способ представления null в JSON. По спецификациям ( RFC 4627 и json.org ):

  2.1.  Значения

 Значение JSON ДОЛЖНО быть объектом, массивом, числом или строкой или одним из
 следующие три буквальных имени:

   false null true

введите описание изображения здесь

Существует только один способ представления 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 который является пустым списком:

 { "myCount": [] } 

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

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

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

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

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

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

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

Согласно спецификации JSON , внешний контейнер не обязательно должен быть словарем (или «объектом»), как это подразумевается в большинстве комментариев выше. Он также может быть списком или голым значением (например, строкой, числом, булевым или нулевым). Если вы хотите представить нулевое значение в 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 
  • MVC-controller: получить объект JSON из тела HTTP?
  • Как десериализовать дату JS с помощью jacksonа?
  • Как конвертировать JSON в HashMap с помощью Gson?
  • Замедленный заказ JSON
  • Как использовать JSON.NET для десериализации в вложенный / рекурсивный словарь и список?
  • Lazy загружает изображения в gridView
  • Итерация над свойствами JsonObject
  • JSON-потребитель полиморфных объектов
  • Пользовательский десериализатор JSON с использованием Gson
  • GUI-based или Web-JSON-редактор, который работает как средство исследования свойств
  • Использование json_encode для объектов в PHP (независимо от области действия)
  • Давайте будем гением компьютера.