Представление 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 ответов:
давайте оценим разбор каждого:
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
есть только один способ представления
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