example - Representando nulo en JSON
jackson json (8)
¿Cuál es el método preferido para devolver valores nulos en JSON? ¿Hay una preferencia diferente por los primitivos?
Por ejemplo, si mi objeto en el servidor tiene un 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 cadenas: si tengo una cadena nula "myString" en el servidor, es la mejor JSON:
{}
o
{
"myString": null
}
o
{
"myStrung": ""
}
o (señor ayudame)
{
"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 las "preferencias personales" parece realista, pero en breve, ya que una comunidad consumirá un mayor número de servicios / fuentes dispares. Los convenios 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:
- Los objetos son preferidos a los primitivos.
- Las colecciones vacías son preferidas a las nulas.
- Los objetos sin valor se representan como nulos.
- Los primitivos 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 de 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>
Cuando se trabaja con código Java y JSON con este ejemplo.
{ "myString" : "" }
Encontré que esto no funcionó
if(obj.myString=="")
pero esto lo hizo.
if(obj.getString("myString").equals(""))
De acuerdo con la especificación JSON , el contenedor más externo no tiene que ser un diccionario (u "objeto") como se indica 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 citas. 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. De manera similar, un diccionario vacío ( {}
) o una lista vacía ( []
) están perfectamente bien, pero tampoco son nulos.
En 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
Elegiría "predeterminado" para el tipo de datos de la variable ( null
para cadenas / objetos, 0
para números), pero de hecho verifico qué código consumirá el objeto esperado. No olvide que a veces hay una distinción entre null
/ predeterminado frente a "no presente".
Revise el patrón de objeto nulo : a veces es mejor pasar un objeto especial en lugar de null
(es decir, []
matriz en lugar de null
para matrices o ""
para cadenas).
Esta es una elección personal y situacional. Lo importante a recordar es que la cadena vacía y el número cero son conceptualmente distintos de null
.
En el caso de un count
es probable que siempre desee un número válido (a menos que el count
sea desconocido o no definido), pero en el caso de cadenas, ¿quién sabe? La cadena vacía podría significar algo en su aplicación. O tal vez no lo hace. Eso depende de usted decidir.
Solo hay una forma de representar null
; Eso es con 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
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 ningún valor:
{ "myCount": null }
sin atributo / atributo faltante
¿Qué pasa si desea transmitir que tiene un objeto sin atributos:
{}
El código del cliente intentará acceder a myCount
y obtener undefined
; no está ahí.
colección vacía
¿Qué myCount
si desea transmitir que tiene un objeto con un atributo myCount
que es una lista vacía?
{ "myCount": [] }
Vamos a evaluar el análisis de cada uno:
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: []}
El tl; dr aquí:
JSON2 es la forma en que la especificación JSON indica que se debe representar
null
. Pero como siempre, depende de lo que esté haciendo; a veces, la forma "correcta" de hacerlo no siempre funciona para su situación. Usa tu juicio y toma una decisión informada.
JSON1 {}
Esto devuelve un objeto vacío. No hay datos allí, y solo te dirá que cualquier clave que estés buscando (ya sea myCount
o alguna otra cosa) es de tipo undefined
.
JSON2 {"myCount": null}
En este caso, myCount
está realmente definido, aunque su valor es null
. Esto no es lo mismo que "ni undefined
ni null
", 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 que false
. Si su declaración condicional evalúa myCount > 0
, entonces valdría la pena tener esto. Además, si está ejecutando cálculos basados en el valor aquí, 0 podría ser útil. Sin embargo, si está intentando realizar una prueba de null
, esto no funcionará en absoluto.
JSON4 {"myString": ""}
En este caso, obtendrás una cadena vacía. De nuevo, como con JSON2, está definido, pero está vacío. Podría probar para if (obj.myString == "")
pero no podría probar para null
o undefined
.
JSON5 {"myString": "null"}
Probablemente esto te va a poner en problemas, porque estás configurando el valor de cadena en nulo; en este caso, obj.myString == "null"
sin embargo, no es == null
.
JSON6 {"myArray": []}
Esto te dirá que tu array myArray
existe, pero está vacío. Esto es útil si está intentando realizar un conteo o evaluación en myArray
. Por ejemplo, supongamos que desea evaluar el número de fotos que un usuario publicó: podría hacer myArray.length
y devolvería 0
: definido, pero no se publicaron fotos.
Yo usaría null
para mostrar que no hay valor para esa clave en particular. Por ejemplo, use null
para representar que "la cantidad de dispositivos en su hogar que se conectan a internet" es desconocida.
Por otro lado, use {}
si esa clave en particular no es aplicable. Por ejemplo, no debe mostrar un recuento, aunque sea null
, a la pregunta "número de autos que tienen conexión a Internet activa" se le pregunta a alguien que no posee ningún automóvil.
Evitaría el incumplimiento de cualquier valor a menos que el predeterminado tenga sentido. Si bien puede decidir usar null
para no representar ningún valor, ciertamente nunca use "null"
para hacerlo.
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 ):
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