¿Cuál es el método preferido para devolver valores nulos en JSON? ¿Hay una preferencia diferente por las primitivas?
Por ejemplo, si mi objeto en el servidor tiene un número entero llamado "myCount" sin valor, el JSON más correcto para ese valor sería:
{}
o
{
"myCount": null
}
o
{
"myCount": 0
}
La misma pregunta para Strings: si tengo una cadena nula "myString" en el servidor, es el mejor JSON:
{}
o
{
"myString": null
}
o
{
"myString": ""
}
o (señor, ayúdame)
{
"myString": "null"
}
Me gusta la convención para que las colecciones se representen en el JSON como una colección vacía http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html
Una matriz vacía estaría representada:
{
"myArray": []
}
EDITAR resumen
El argumento de 'preferencia personal' parece realista, pero miope en eso, como comunidad consumiremos un número cada vez mayor de servicios / fuentes dispares. Las convenciones para la estructura JSON ayudarían a normalizar el consumo y la reutilización de dichos servicios. En cuanto a establecer un estándar, sugeriría adoptar la mayoría de las convenciones de Jackson con algunas excepciones:
- Se prefieren los objetos sobre los primitivos.
- Se prefieren las colecciones vacías a las nulas.
- Los objetos sin valor se representan como nulos.
- Las primitivas devuelven su valor.
Si está devolviendo un objeto JSON con valores mayormente nulos, puede tener un candidato para refactorizar en múltiples servicios.
{
"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
}
El JSON anterior se generó a partir de la siguiente clase 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()));
}
}
Dependencia de Maven:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.0</version>
</dependency>
null
considerar si su cliente es mejor con la cadena vacía o sinull
una cadena que contiene la palabra "nulo" no se puede distinguir de un valor válido, no lo haga.NSNull
clase definida que tiene una instancia singleton. Una referencia a esa instancia es equivalente a la de JSONnull
. Supongo que otro idioma podría hacer lo mismo. Por supuesto, uno tendría que verificar la clase del objeto recibido antes de lanzar a la clase presunta, por lo tanto, tenga "nulo conocimiento".Collections.emptyList()
). Al hacerlo, se evitan errores de referencia nulos que, de lo contrario, pueden ser un dolor.Null
clase (útil) porque solo podría asignar sus valores a objetos de su propio tipo o de tipoObject
.Respuestas:
Vamos a evaluar el análisis de cada uno:
http://jsfiddle.net/brandonscript/Y2dGv/
JSON1
{}
Esto devuelve un objeto vacío. No hay datos allí, y solo le dirá que cualquier clave que esté buscando (ya sea
myCount
u otra cosa) es de tipoundefined
.JSON2
{"myCount": null}
En este caso,
myCount
se define realmente, aunque su valor esnull
. Esto no es lo mismo que "noundefined
y nonull
", y si estuviera probando una condición u otra, esto podría tener éxito mientras que JSON1 fallaría.Esta es la forma definitiva de representar
null
según la especificación JSON .JSON3
{"myCount": 0}
En este caso, myCount es 0. Eso no es lo mismo que
null
, y no es lo mismo quefalse
. Si su declaración condicional se evalúamyCount > 0
, entonces podría valer la pena tenerla. Además, si está ejecutando cálculos basados en el valor aquí, 0 podría ser útil.null
Sin embargo, si está tratando de realizar una prueba , esto en realidad no va a funcionar en absoluto.JSON4
{"myString": ""}
En este caso, obtienes una cadena vacía. De nuevo, como con JSON2, está definido, pero está vacío. Podrías hacer una prueba
if (obj.myString == "")
pero no podrías hacer una prueba paranull
oundefined
.JSON5
{"myString": "null"}
Esto probablemente lo meterá en problemas, porque está configurando el valor de la cadena en nulo; en este caso,
obj.myString == "null"
sin embargo, es no== null
.JSON6
{"myArray": []}
Esto le dirá que su matriz
myArray
existe, pero está vacía. Esto es útil si está intentando realizar un conteo o evaluaciónmyArray
. Por ejemplo, supongamos que desea evaluar la cantidad de fotos que publicó un usuario; podría hacerlomyArray.length
y volvería0
: definido, pero no hay fotos publicadas.fuente
JSON1
decir{}
null
no es cero No es un valor, per se : es un valor fuera del dominio de la variable que indica datos faltantes o desconocidos.Solo hay una forma de representar
null
en JSON. Según las especificaciones ( RFC 4627 y json.org ):fuente
json = '{"myValue":}';
Solo hay una forma de representar
null
; eso es connull
.Es decir; si alguno de los clientes que consumen su representación JSON usa el
===
operador; Podría ser un problema para ellos.sin valor
Si desea transmitir que tiene un objeto cuyo atributo
myCount
no tiene valor:sin atributo / atributo faltante
¿Qué pasaría si transmitiera que tiene un objeto sin atributos?
El código del cliente intentará acceder
myCount
y obtenerundefined
; no está ahí.colección vacía
¿Qué pasaría si transmitiera que tiene un objeto con un atributo
myCount
que es una lista vacía?fuente
Solía
null
mostrar que no hay valor para esa clave en particular. Por ejemplo, usenull
para representar que "la cantidad de dispositivos en su hogar se conecta a internet" es desconocida.Por otro lado, use
{}
si esa clave en particular no es aplicable. Por ejemplo, no debe mostrar un recuento, incluso sinull
, a la pregunta "número de automóviles que tienen conexión activa a Internet" se le hace a alguien que no posee ningún automóvil.Evitaría el valor predeterminado a menos que ese valor predeterminado tenga sentido. Si bien puede decidir usarlo
null
para no representar ningún valor, ciertamente nunca"null"
lo haga.fuente
Elegiría "predeterminado" para el tipo de datos de la variable (
null
para cadenas / objetos,0
para números), pero de hecho verificaría qué código que consumirá el objeto espera. No olvide que a veces hay una distinción entrenull
/ default vs. "no presente".Verifique el patrón de objeto nulo : a veces es mejor pasar algún objeto especial en lugar de
null
(es decir,[]
matriz en lugar denull
para matrices o""
cadenas).fuente
Esta es una elección personal y situacional. Lo importante para recordar es que la cadena vacía y el número cero son conceptualmente distintos de
null
.En el caso de un
count
, probablemente siempre desee un número válido (a menos quecount
sea desconocido o indefinido), pero en el caso de las cadenas, ¿quién sabe? La cadena vacía podría significar algo en su aplicación. O tal vez no. Eso depende de ti decidir.fuente
Según la especificación JSON , el contenedor más externo no tiene que ser un diccionario (u 'objeto') como se implica en la mayoría de los comentarios anteriores. También puede ser una lista o un valor simple (es decir, cadena, número, booleano o nulo). Si desea representar un valor nulo en JSON, toda la cadena JSON (excluyendo las comillas que contienen la cadena JSON) es simplemente
null
. Sin llaves, sin corchetes, sin comillas. Puede especificar un diccionario que contenga una clave con un valor nulo ({"key1":null}
), o una lista con un valor nulo ([null]
), pero estos no son valores nulos en sí mismos, son diccionarios y listas adecuados. Del mismo modo, un diccionario vacío ({}
) o una lista vacía ([]
) están perfectamente bien, pero tampoco son nulos.En Python:
fuente
null
constituye un JSON válido. El texto del cuerpo principal y las ilustraciones allí son ambiguos y, si algo parece sugerir, solo los objetos y las matrices son válidos en la raíz.