在JSON中表示null

phe*_*ris 365 json jackson gson

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

例如,如果服务器上的对象有一个名为"myCount"且没有值的Integer,那么该值的最正确的JSON将是:

{}
Run Code Online (Sandbox Code Playgroud)

要么

{
    "myCount": null
}
Run Code Online (Sandbox Code Playgroud)

要么

{
    "myCount": 0
}
Run Code Online (Sandbox Code Playgroud)

字符串的相同问题 - 如果我在服务器上有一个空字符串"myString",则是最好的JSON:

{}
Run Code Online (Sandbox Code Playgroud)

要么

{
    "myString": null
}
Run Code Online (Sandbox Code Playgroud)

要么

{
    "myString": ""
}
Run Code Online (Sandbox Code Playgroud)

或者(上帝帮助我)

{
    "myString": "null"
}
Run Code Online (Sandbox Code Playgroud)

我喜欢集合的约定在JSON中表示为空集合http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html

将显示一个空数组:

{
    "myArray": []
}
Run Code Online (Sandbox Code Playgroud)

编辑摘要

"个人偏好"的观点似乎是现实的,但很短暂,因为社区将消耗更多不同的服务/来源.JSON结构的约定将有助于规范化所述服务的消耗和重用.就建立标准而言,我建议采用大多数杰克逊公约,但有一些例外:

  • 对象比基元更受欢迎.
  • 空集合优先于null.
  • 没有值的对象表示为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

}
Run Code Online (Sandbox Code Playgroud)

上面的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()));
    }
}
Run Code Online (Sandbox Code Playgroud)

Maven依赖:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.3.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

bra*_*ipt 326

让我们评估每个解析:

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: []}
Run Code Online (Sandbox Code Playgroud)

TL;博士在这里:

JSON2JSON规范表明null应该表示的方式.但与往常一样,这取决于你正在做什么 - 有时候"正确"的做法并不总是适合你的情况.用你的判断做出明智的决定.


JSON1 {}

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


JSON2 {"myCount": null}

在这种情况下,myCount实际上是定义的,尽管它的值是null.这是一样的两个"不undefined,不null",如果你是一个条件或其他测试,这可能会成功,而JSON1会失败.

这是代表明确的方式nullJSON的规范.


JSON3 {"myCount": 0}

在这种情况下,myCount是0.这null与它不一样,并且它不一样false.如果你的条件语句评估myCount > 0,那么这可能是值得的.此外,如果您根据此处的值运行计算,则0可能很有用.null但是,如果您正在尝试测试,那实际上根本不起作用.


JSON4 {"myString": ""}

在这种情况下,您将获得一个空字符串.同样,与JSON2一样,它已定义,但它是空的.你可以测试,if (obj.myString == "")但你无法测试nullundefined.


JSON5 {"myString": "null"}

这可能会让你遇到麻烦,因为你将字符串值设置为null; 在这种情况下,obj.myString == "null"然而事实并非如此 == null.


JSON6 {"myArray": []}

这将告诉您数组myArray存在,但它是空的.如果您正在尝试执行计数或评估,这将非常有用myArray.例如,假设您想要评估用户发布的照片​​数量 - 您可以这样做myArray.length,它将返回0:已定义,但未发布照片.

  • 没有 `{"myObject": {}}` 选项吗?是否可以将值设置为空对象? (2认同)

Nic*_*rey 196

null不是零.这不是一个值,本身:它是变量,指示丢失的或未知的数据的域之外的值.

null在JSON中只有一种表示方式.根据规范(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

在此输入图像描述

  • @Richard A Quadling - 我是Hal Abelson的追随者"必须为人们阅读程序,而且只能偶然为机器执行".我更喜欢"null"这个词,确认程序员的意图,而不仅仅是意外遗漏的问题. (109认同)
  • @Dave May:"JSON值不是程序" - 我的观点是以明确的方式表示信号意图.是的,它需要额外的四个字符,对于某些应用程序,差异可能很大.但在许多情况下,使错误*看起来错误的好处远远超过了次要优化的好处. (13认同)
  • 另请注意,如果您遇到4个ASCII字符的问题,JSON不是最佳方法,请查看[Binary JSON](http://bsonspec.org/)或更好的纯二进制格式. (11认同)
  • @Dave另外,根据json.org,JSON"对人类来说很容易读写." (10认同)
  • 遗憾的是,必须存在null.4个字符什么都没有.简单地完全排除该值会很好.`json ='{"myValue":}';` (8认同)

dno*_*zay 21

只有一种方式可以代表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
Run Code Online (Sandbox Code Playgroud)

也就是说; 如果任何使用您的JSON表示的客户端使用该===运算符; 这可能是他们的问题.

没有价值

如果你想传达你有一个属性myCount没有值的对象:

{ "myCount": null }
Run Code Online (Sandbox Code Playgroud)

没有属性/缺失属性

如果你传达的是你有一个没有属性的对象怎么办:

{}
Run Code Online (Sandbox Code Playgroud)

客户端代码将尝试访问myCount并获取undefined; 它不在那里.

空集合

如果您传达的是具有属性myCount为空列表的对象,该怎么办?

{ "myCount": [] }
Run Code Online (Sandbox Code Playgroud)


mar*_*seu 14

我会null用来表明该特定键没有任何价值.例如,用于null表示"您家中的设备连接到互联网的数量"是未知的.

另一方面,{}如果该特定密钥不适用,请使用.例如,即使null对于没有拥有任何汽车的人询问"具有有效互联网连接的汽车数量"这一问题,也不应显示计数.

除非默认有意义,否则我会避免违约.虽然您可能决定使用null不代表任何价值,但绝对不"null"会这样做.


Ale*_*kov 7

我会为变量的数据类型选择"default"(null对于字符串/对象,0对于数字),但确实检查将使用该对象所期望的代码.不要忘记,null/ default与"not present" 之间有时会有区别.

检查空对象模式 - 有时最好传递一些特殊对象而不是null(即[]数组而不是null数组或""字符串).