在JSON中表示null

在JSON中返回空值的首选方法是什么?对原语有不同的偏好吗?

例如,如果我在服务器上的对象有一个名为“mycount”的Integer;如果没有值,则该值的最正确JSON是:

{}

{
"myCount": null
}

{
"myCount": 0
}

同样的问题对于字符串-如果我有一个空字符串& myString",是最好的JSON:

{}

{
"myString": null
}

{
"myString": ""
}

或者(上帝帮助我)

{
"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>
889282 次浏览

我将为变量的数据类型选择“默认”(null为字符串/对象,0为数字),但确实检查将消费对象期望的代码。不要忘记,有时null/default和null/default之间是有区别的。“不存在”。

检查空对象模式 -有时传递一些特殊的对象而不是null更好(例如,[]数组而不是null数组或""字符串)。

这是个人的、情境性的选择。重要的是要记住,空字符串和数字0在概念上与null是不同的。

对于count,您可能总是想要一些有效的数字(除非count是未知的或未定义的),但对于字符串,谁知道呢?空字符串可以在应用程序中的意思是。也可能不是。这由你来决定。

我将使用null来表示该特定键没有值。例如,使用null表示“您家庭中连接到互联网的设备数量”是未知的。

另一方面,如果特定的键不适用,则使用{}。例如,你不应该显示一个数字,即使null,对于一个没有任何汽车的人被问到的问题“有活跃互联网连接的汽车数量”。

我会避免默认值,除非默认值有意义。虽然您可以决定使用null来表示没有值,但绝对不要使用"null"来这样做。

让我们来评估一下每一个的解析:

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;:

json2变量中的片段是JSON规范表示应该表示null的方式。但一如既往,这取决于你在做什么——有时“正确的”;做事的方法并不总是适用于你的情况。运用你的判断力,做出明智的决定。


JSON1 # EYZ0

这将返回一个空对象。这里没有数据,它只会告诉您您正在寻找的任何键(无论是myCount还是其他键)的类型是undefined


JSON2 # EYZ0

在本例中,实际上定义了myCount,尽管它的值是null。这是,与“不是undefined”和“不是# eyz1”是一样的,如果您正在测试一个或另一个条件,这可能会成功,而JSON1将失败。

这是每JSON规范表示null的最终方式。


JSON3 # EYZ0

在本例中,myCount为0。这和null不一样,也和false不一样。如果条件语句计算的是myCount > 0,那么这可能是值得的。此外,如果基于这里的值运行计算,0可能有用。然而,如果您试图测试null,这实际上根本不会起作用。


JSON4 # EYZ0

在本例中,您将得到一个空字符串。同样,与JSON2一样,它是有定义的,但它是空的。您可以测试if (obj.myString == ""),但不能测试nullundefined


JSON5 # EYZ0

这可能会给您带来麻烦,因为您将字符串值设置为null;在这种情况下,obj.myString == "null",但它是 == null


JSON6 # EYZ0

这将告诉您数组myArray存在,但它是空的。如果您试图对myArray执行计数或计算,这很有用。例如,假设你想计算一个用户发布的照片数量——你可以执行myArray.length,它将返回0:已定义,但没有照片发布。

null不是零。本身不是一个值:它是一个变量域之外的值,表示缺失或未知数据。

在JSON中只有一种方法来表示null。根据规格(RFC 4627json.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": [] }

根据JSON规范,最外层的容器不必是字典(或“对象”),正如上面大多数注释所暗示的那样。它也可以是一个列表或一个空值(即字符串,数字,布尔或null)。如果您想在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

'null'最适合实际使用

FWIW,以PHP为例,PHP将空集解释为PHP的条目…

// This loop will iterate one item with the value 'the car'
$empty_json = '["the car"]';
$some_json_array = json_decode($empty_json;


foreach ($some_json_array as $i) {
echo "PHP sees one item";
}

输出:# EYZ0

// This loop will iterate one item, but with no values
$empty_json = '[""]';
$some_json_array = json_decode($empty_json;


foreach ($some_json_array as $i) {
echo "PHP sees: $i";
}

输出:# EYZ0

// This loop will iterate nothing because PHP's `json_decode()` function knew it was `null`
$empty_json = 'null';
$some_json_array = json_decode($empty_json;


foreach ($some_json_array as $i) {
echo "PHP sees one item";
}

输出:(什么都没有,foreach不会循环)