2011-01-27 20 views
13

Estoy usando la biblioteca de jackson para serializar/deserializar a/desde JSON. Necesito que este JSON tenga el tamaño más pequeño posible, así que habilité la característica ALLOW_UNQUOTED_FIELD_NAMES para eliminar todas las comillas. Sé que eliminar citas no es estándar, pero hacer json pequeño es un requisito difícil del proyecto. El JSON generado funciona, pero cuando he intentando leer el valor JSON que estoy recibiendo una excepción:ALLOW_UNQUOTED_FIELD_NAMES en la biblioteca jackson JSON

org.codehaus.jackson.JsonParseException: carácter inesperado ('9' (código 57)): esperaba nombre válido carácter (para el nombre sin comillas) o comillas dobles (para las citas) para iniciar nombre del campo en [Origen: [email protected]; línea: 1, columna: 3]

La excepción anterior se inicia cuando leí este json:

{90110a2e-febd-470f-afa4-cf7e890d31b9:0,eec652ad-a4d9-4eb1-8d24-7c1a0c29449f:1} 

La forma leí que es:

Map<String, Object> valuesMap = oM.readValue(json, new TypeReference<Map<String, Object>>() {}); 

y el objeto mapper que uso ambos para leer y escribir los valores es:

private static final ObjectMapper om = new ObjectMapper(); 
static { 
    om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false); 
    om.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 
    om.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, true); 
    om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
    om.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); 
} 

Estoy usando la versión 1.6.3 de Jackson, tanto en el proyecto emisor como en el receptor. La versión necesaria para esta característica es 1.2+, así que pensé que tal vez no estaba usando esta versión, pero mi receptor es una aplicación de Spring y he comprobado que la biblioteca instalada en la carpeta libs es 1.6.3.

¿Qué puedo estar haciendo mal? Tal vez esta característica no se puede usar con mapas.

Tengo otra pregunta, hasta ahora solo estoy enviando un mapa donde la clave tiene solo un valor de uuid y el valor es un número. ¿Puedo tener algún problema si envío un valor con caracteres especiales con la característica ALLOW_UNQUOTED_FIELD_NAMES activada? Will jackson escapará de estos personajes?

Gracias.

Respuesta

5

Parece que Jackson con QUOTE_FIELD_NAMES en ciertos casos produce una salida tal que no puede leerse incluso con ALLOW_UNQUOTED_FIELD_NAMES activado. Probablemente necesite implementar JsonParser personalizado para el análisis de entrada no estándar.

El problema es que está generando JSON no estándar y no hay garantías de que el cliente lo maneje correctamente. Sin embargo, si no lo expone fuera de su (s) aplicación (es) y se preocupa mucho por el tamaño, podría analizar/generar un formato binario como el Smile de Jackson. Ver http://www.cowtowncoder.com/blog/archives/2010/09/entry_418.html (2.4).

+0

Muy buen punto sobre Smile: puede ser compacto, esp. cuando se habilitan las referencias de valor de cadena (si hay muchos valores de cadena repetidos, como valores enumerados) – StaxMan

2

Creo que el problema está relacionado con Javascript sintax y no con Jackson ni con JSON.

En Javascript, un nombre es una letra opcionalmente seguida de una o más letras, dígitos o barras inferiores, por lo que 90110a2e-febd-470f-afa4-cf7e890d31b9 no es un nombre legal de Javascript.

Las comillas sobre el nombre de una propiedad son opcionales si el nombre sería un nombre de JavaScript legal y no una palabra reservada. Por lo tanto, se requieren citas alrededor de "primer nombre", pero son opcionales alrededor de first_name.

Por cierto, si está tan preocupado por el tamaño de JSON, ¿por qué no lo descomprime gzip?

+0

Gracias lo había pensado, pero no estaba seguro de si las variables eran legales o no. Aunque el json no se usa en javascript (se envía desde un cliente Java a una aplicación JEE), lo que diga podría ser correcto. En cuanto a gzip, ya estoy enviando el json con cremallera, pero gracias por la idea de todos modos. – Javi

6

Ok, la respuesta de Pingw33n es bastante correcta, creo. Entonces: sí, puedes usar la función; pero es más bien heurístico, ya que no hay ninguna especificación sobre cómo deberían funcionar los nombres sin comillas (¡después de todo, JSON permite nombres para todos los nombres!); o, ¿qué pasa si se va a utilizar un mecanismo de escape, nadie sabe qué se debe escribir o aceptar?

En este caso particular, es probable que el carácter '-' cause un problema. No es una parte legal del nombre Javascript, que es la aproximación que usa Jackson.

Una posible solución sería que Jackson escapara de tales caracteres en los nombres de las propiedades (no recuerdo cómo se hace actualmente, si se citan los nombres de los caracteres). Si puede resolver un caso de prueba simple, puede presentar una solicitud de mejora de Jira al Jackson Jira para obtener el escapado agregado (y asegurarse de que el analizador puede eliminar la versión normal de la barra invertida).

+1

Oh. En realidad, es incluso más simple que eso: dado que los identificadores de JavaScript no pueden comenzar con números, eso es lo que causa el problema. También es posible relajar esto para el modo ALLOW_UNQUOTED_FIELD_NAMES; para esto, una solicitud de función Jira ayudaría. – StaxMan

Cuestiones relacionadas