Представление 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
