Introducción a JSON

2
78608

Introducción a JSON.

0. Índice de contenidos.

1. Introducción

JSON es un formato ligero para el intercambio de datos. Tenemos una buena introdución al mismo en el siguiente artículo de la wikipedia: JSON.

JSON es un subconjunto del lenguaje javascript que se basa en la construcción de una lista ordenada de valores, listas de objetos, que pueden incluir a su vez tablas hash, objetos con una colección de pares nombre/valor.

Me voy a limitar a comentar que se puede usar como alternativa a la necesidad de XML en el intercambio de información vía Ajax y que podemos hacer uso del mismo:

  • si el volumen de datos que manejamos excede de lo razonable: Yahoo y Google lo usan en sus clientes de correo web para aligerar el peso de los documentos de intercambio,
  • o si odiamos XML, porque aludir a la complejidad o el coste del parseo del XML en cliente, pudiéndo llevarlo a cabo con DOM, no me parece una buena excusa, aunque se admiten discusiones…

En este tutorial vamos a ver un ejemplo de uso sencillo y cómo podemos modificar el ejemplo publicado en el tutorial de prototype.js,
para adaptar la comunicación de XML a JSON.

2. Adaptar una estructura XML a JSON.

Para adaptar una estructura XML a JSON podemos usar las recomendaciones de éste artículo de O’Reilly: Converting Between XML and JSON,
en el que proponen usar la misma nomenclatura de nodos, el contenido textual nombrarlo con «#text» y para nombrar atributos usar la arroba como prefijo (para que se asemeje a un parseo con DOM), de modo que si tenemos este XML:



  Alcobendas
  Miraflores de la Sierra
  San Fernando de Henares

Su documento JSON sería el siguiente:

{"poblaciones":[
	{"poblacion": { "@id": "0", "#text": "Alcobendas" }}
,
	{"poblacion": { "@id": "1", "#text": "Miraflores de la Sierra" }}
,
	{"poblacion": { "@id": "2", "#text": "San Fernando de Henares" }}
]}

Para analizar el contenido del objeto JSON tenemos que evaluar primero la cadena usando el procedimiento eval(») de javascript


En la línea 3 del script tenemos un ejemplo de cómo acceder al contenido textual de un nodo, con la nomenclatura recomendada.

Pero el formato del documento JSON es libre y nosotros podemos construir nuestras propias estructuras. Haciendo caso omiso de las recomendaciones, el mismo XML podría construirse como un
objeto JSON de la siguiente manera:

{"poblacion":[ 
  { "id": "0", "nombre": "Alcobendas" }
  ,
  { "id": "1", "nombre": "Miraflores de la Sierra" }
  ,
  { "id": "2", "nombre": "San Fernando de Henares" }
]}

Para obtener el contenido del objeto JSON accederíamos de la siguiente manera:


3. JSON y Ajax con prototype.js.

El procedimiento eval('') de javascript puede acarrear posibles problemas de seguridad si la fuente de la que obtenemos la cadena a evaluar no es segura, puesto que lo evalua sin llevar a cabo un
parseo, esto es, sin comprobar la estructura del objeto JSON. Si dentro de la cadena se introduce una instrucción javascript será ejecutada.

La librería Prototype.js integra JSON desde dos puntos de vista:

  • convierte "objetos" javascript en objetos JSON, mediante el uso del método Object.toJSON.
  • parsea cadenas evaluándolas en objetos JSON, mediante el uso del método String.evalJSON

La función evalJSON sustituye al procedimiento nativo eval('') e implementa el paso de un parámetro que fuerza una comprobación previa del contenido de la cadena en busca de código ejecutable o malicioso,
el parámetro se inicializa a true, con lo que la comprobación se realiza por defecto.
En caso de encontrar algún código ejecutable lanza un SyntaxError.

Podeis probar a ejecutar el siguiente código:

    

4. Modificación del ejemplo: recarga controlada de un selector con Prototype.js.

Vamos a modificar el ejemplo de recarga controlada de selectores para que la comunicación se lleve a cabo mediante objetos JSON.

En primer lugar, modificamos el contenido de la jsp que da servicio a las peticiones de recuperación de las poblaciones para una provincia [services/poblaciones.jsp] con el siguiente contenido:

{"poblaciones":[
<% 
	response.setContentType("application/json");
	String[] poblaciones = null;
	String id = request.getParameter("id");
	if (id == null) id = "1";
	if (id.equals("1")) 
	{
		poblaciones = new String[] { "Alcobendas", "Miraflores de la Sierra", "San Fernando de Henares" };
	} 
	else if (id.equals("2")) 
	{
		poblaciones = new String[] { "El Palo", "La Cala del Moral", "Rincon de la Victoria" };
	}
	else 
	{
		poblaciones = new String[] { "" };
	}

	for(int i = 0; i < poblaciones.length; i++)
	{
		if (i > 0) out.print(",");
%>
	{"poblacion": { "@id": "<%=i%>", "#text": "<%=poblaciones[i]%>" }}
<%
	}
%>
]}

En vez de devolver XML, devuelve una cadena con un objeto JSON, construido conforme a las recomendaciones de O'Reilly.

Si comprobamos el resultado de las peticiones a la jsp vía Ajax a través de la consola de Firebug de Firefox tendremos algo parecido a lo siguiente:

Vista de la consola de firebug

En segundo lugar, modificamos el javascript que controla el evento onchange() sobre el selector de provincias [script/reloaders.js] para que evalue la cadena que devuelve el servidor y la analice conforme al nuevo formato.

function reloadPoblaciones(selector)
{
    // la url del servicio que nos devuelve el listado de poblicaciones para una provincia
    var surl = "services/poblaciones.jsp";

    // parametro con el identificador de la proviencia
    var params = "id="+selector.value;
    // debugger;

    // prototype Ajax.Request: petición de servicio
    var response = new Ajax.Request(surl, {asynchronous: false, method: 'post', parameters: params}).transport;

    // en vez de > var json = eval( '(' + response.responseText + ')' );
    var json = response.responseText.evalJSON(); 

    // prototype getElementById: obtenemos el selector de poblaciones del Árbol DOM
    var select = $("poblaciones");
    select.options.length = 0;
    
    // si tenemos alguna poblacion para la provincia
	  if (json.poblaciones.length != 0 )
	  {
        // asignamos un valor por defecto en el primer option del selector de poblaciones
        select.options.add( 
            new Option("Seleccione una poblacion",""));
        // por cada una de las poblaciones obtenidas
        for(i = 0 ; i < json.poblaciones.length; i++ )
        {
        	select.options.add( 
        		new Option( json.poblaciones[i].poblacion["#text"],
        				json.poblaciones[i].poblacion["@id"]));
        }
        // seleccionamos el option por defecto
        select.options[0].selected = "selected";
    }
}

Hacemos uso de la función evalJSON() [línea 14], que lleva a cabo una comprobación previa del contenido de la cadena a evaluar. La cadena a evaluar la obtenemos mediante una llamada al método responseText en vez del método responseXML.

El objeto JSON lo analizamos como hemos comentado en el punto 2 [líneas 21 a 35].

El resultado final del ejemplo no difiere del realizado con documentos XML, lo que hemos modificado es la implementación, no la funcionalidad.

5. Conclusiones

Lo ideal es evitar el tener que bajar a estos niveles en la construcción de aplicaciones web, el uso de componentes para la construcción de las interfaces de usuario y la generalización de frameworks que dan una solución única a la comunicación entre el servidor y el cliente ayudan a ello.

Pero no todas las aplicaciones y proyectos nos permiten eludir este tipo de problemática, si estáis usando Prototype.js y el XML que parseais se ha convertido en un problema, aquí tenéis una alternativa.

Para ampliar información sobre JSON podeís consultar en siguiente enlace json.org.

Para saber más sobre Prototype.js este otro prototypejs.org.

Un saludo.

Jose

2 COMENTARIOS

  1. Nuevamente felicitaciones, destacaría también la cantidad de lineas de JSON que es inferiormente mas pequeña que la de un XML en aplicaciones mas grandes y ahi si que se nota una gran una gran diferencia… esto como aporte a este buen articulo.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad