Qual é o método preferido para retornar valores nulos em JSON? Existe uma preferência diferente para primitivas?
Por exemplo, se meu objeto no servidor tiver um número inteiro chamado "myCount" sem valor, o JSON mais correto para esse valor seria:
{}
ou
{
"myCount": null
}
ou
{
"myCount": 0
}
Mesma pergunta para Strings - se eu tiver uma string nula "myString" no servidor, é o melhor JSON:
{}
ou
{
"myString": null
}
ou
{
"myString": ""
}
ou (senhor me ajude)
{
"myString": "null"
}
Gosto da convenção de coleções ser representada no JSON como uma coleção vazia http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html
Uma matriz vazia seria representada:
{
"myArray": []
}
Resumo do EDIT
O argumento de 'preferência pessoal' parece realista, mas míope, como comunidade, estaremos consumindo um número cada vez maior de serviços / fontes diferentes. As convenções para a estrutura JSON ajudariam a normalizar o consumo e a reutilização desses serviços. Quanto ao estabelecimento de um padrão, eu sugeriria a adoção da maioria das convenções de Jackson com algumas exceções:
- Os objetos são preferíveis aos primitivos.
- Coleções vazias são preferidas a nulas.
- Objetos sem valor são representados como nulos.
- As primitivas retornam seu valor.
Se você estiver retornando um objeto JSON com valores principalmente nulos, poderá ter um candidato para refatorar em vários serviços.
{
"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
}
O JSON acima foi gerado a partir da seguinte classe 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()));
}
}
Dependência do Maven:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.0</version>
</dependency>
null
, considere se o seu cliente é melhor com a string vazia ounull
- uma string contendo a palavra "null" é indistinguível de um valor válido, não faça isso.NSNull
classe definida que possui uma instância singleton. Uma referência a essa instância é equivalente a JSONnull
. Eu acho que outro idioma poderia fazer a mesma coisa. Obviamente, seria necessário verificar a classe do objeto recebido antes de converter para a classe presumida - ter "reconhecimento nulo", por assim dizer.Collections.emptyList()
). Fazer isso evita erros de referência nulos que, caso contrário, podem ser uma dor.Null
classe (útil) porque só seria capaz de atribuir seus valores a objetos de seu próprio tipo ou tipoObject
.Respostas:
Vamos avaliar a análise de cada um:
http://jsfiddle.net/brandonscript/Y2dGv/
JSON1
{}
Isso retorna um objeto vazio. Não há dados lá, e isso só lhe dirá que qualquer chave que você esteja procurando (seja ela
myCount
ou outra coisa) é do tipoundefined
.JSON2
{"myCount": null}
Nesse caso,
myCount
é realmente definido, embora seu valor sejanull
. Isso não é o mesmo que "nãoundefined
e nãonull
" e, se você estivesse testando uma condição ou outra, isso poderia ser bem-sucedido, enquanto o JSON1 falharia.Essa é a maneira definitiva de representar de
null
acordo com a especificação JSON .JSON3
{"myCount": 0}
Nesse caso, myCount é 0. Isso não é o mesmo que
null
e não é o mesmo quefalse
. Se sua declaração condicional for avaliadamyCount > 0
, isso pode valer a pena. Além disso, se você estiver executando cálculos com base no valor aqui, 0 pode ser útil. Se você estiver tentando testar, nonull
entanto, isso realmente não vai funcionar.JSON4
{"myString": ""}
Nesse caso, você está recebendo uma string vazia. Novamente, como no JSON2, ele está definido, mas está vazio. Você pode testar,
if (obj.myString == "")
mas não pode testarnull
ouundefined
.JSON5
{"myString": "null"}
Isso provavelmente vai causar problemas, porque você está definindo o valor da string como nulo; neste caso,
obj.myString == "null"
no entanto, é não== null
.JSON6
{"myArray": []}
Isso informará que sua matriz
myArray
existe, mas está vazia. Isso é útil se você estiver tentando realizar uma contagem ou avaliaçãomyArray
. Por exemplo, digamos que você queira avaliar o número de fotos que um usuário postou - você poderia fazermyArray.length
e ele retornaria0
: definido, mas sem fotos postadas.fonte
JSON1
ie{}
null
não é zero. Não é um valor em si : é um valor fora do domínio da variável que indica dados ausentes ou desconhecidos.Existe apenas uma maneira de representar
null
no JSON. De acordo com as especificações ( RFC 4627 e json.org ):fonte
json = '{"myValue":}';
Existe apenas uma maneira de representar
null
; isso é comnull
.Isso é para dizer; se algum dos clientes que consome sua representação JSON usar o
===
operador; poderia ser um problema para eles.sem valor
Se você deseja transmitir que possui um objeto cujo atributo
myCount
não tem valor:nenhum atributo / atributo ausente
E se você transmitir que possui um objeto sem atributos:
O código do cliente tentará acessar
myCount
e obterundefined
; não está lá.coleção vazia
E se você transmitir que possui um objeto com um atributo
myCount
que é uma lista vazia:fonte
Eu usaria
null
para mostrar que não há valor para essa chave específica. Por exemplo, usenull
para representar que "o número de dispositivos em sua casa se conecta à Internet" é desconhecido.Por outro lado, use
{}
se essa chave específica não for aplicável. Por exemplo, você não deve mostrar uma contagem, mesmo quenull
a pergunta "número de carros com conexão ativa à Internet" seja solicitada a alguém que não possui carros.Eu evitaria padronizar qualquer valor, a menos que esse padrão faça sentido. Embora você decida usar
null
para não representar nenhum valor, certamente nunca o"null"
fará.fonte
Eu escolheria "default" para o tipo de dados da variável (
null
para strings / objetos,0
para números), mas, de fato, verificaria qual código que consumirá o objeto espera. Não se esqueça, às vezes há uma distinção entrenull
/ default vs. "not present".Confira o padrão de objetos nulos - às vezes é melhor passar algum objeto especial em vez de
null
(ou seja,[]
matriz em vez denull
matrizes ou""
seqüências de caracteres).fonte
Esta é uma escolha pessoal e situacional. O importante é lembrar que a sequência vazia e o número zero são conceitualmente distintos
null
.No caso de um,
count
você provavelmente sempre quer um número válido (a menos quecount
seja desconhecido ou indefinido), mas no caso de strings, quem sabe? A cadeia vazia pode significar algo no seu aplicativo. Ou talvez não. Cabe a você decidir.fonte
De acordo com a especificação JSON , o contêiner mais externo não precisa ser um dicionário (ou 'objeto'), como está implícito na maioria dos comentários acima. Também pode ser uma lista ou um valor simples (ou seja, string, número, booleano ou nulo). Se você deseja representar um valor nulo em JSON, a cadeia JSON inteira (excluindo as aspas que contêm a cadeia JSON) é simples
null
. Sem chaves, sem colchetes, sem aspas. Você pode especificar um dicionário que contenha uma chave com valor nulo ({"key1":null}
) ou uma lista com valor nulo ([null]
), mas esses valores não são nulos - eles são dicionários e listas adequados. Da mesma forma, um dicionário vazio ({}
) ou uma lista vazia ([]
) são perfeitamente adequados, mas também não são nulos.Em Python:
fonte
null
é um JSON válido. O texto e as ilustrações do corpo principal são ambíguos e, se algo parecer sugerir, apenas objetos e matrizes são válidos na raiz.