Construcción personalizada de objetos JSON en cliente (JavaScript)

5
59769

Construcción personalizada de objetos JSON en el cliente (JavaScript)

Introducción

JSON es un formato de intercambio de datos que por su ligereza se ha convertido en un estándar alternativo a XML. (Introducción a JSON)

A modo informativo comentar que se puede usar XPATH y XSLT sobre JSON, busca un poco si te interesa el tema.

En este tutorial voy a explicar como construir manualmente objetos JSON en JavaScript para que la serialización de un formulario (o de lo que sea) se adapte a vuestras necesidades
y que la serialización sea más correcta semánticamente.

Además usando esta serialización personalizada, podremos utilizar de manera más directa librerías como Jackson así como las anotaciones @ResponseBody y @RequestBody de Spring MVC para deserializar automáticamente a objetos JAVA en la parte servidora los datos enviados en formato JSON desde el cliente.

Se comprende mejor con un ejemplo:

Ejemplo

Imagina que queremos recoger mediante un formulario HTML los productos (N) que hay en un determinado pedido (1):

Dicho formulario podría ser el siguiente (le he dado unos valores iniciales a cada uno de los campos, haz clic en cada uno de los botones):











El código HTML es: (Haz clic aquí para ampliar)

Captura de HTML del formulario

Si quisieramos modelizar ese negocio en lenguaje JAVA, las clases resultantes serían algo como (observe que un pedido tiene una lista de productos):

public class Pedido {
	private String codigo;
	private String descripcion;
	private Set productos;
		
	public Pedido(){
		this.productos = new HashSet();
	}
				
	// los getters, setters, hashCode, equals,..
				
	public void addProducto(Producto producto){
		this.productos.add(producto);
	}
				
	// Esto no es del todo correcto, desencapsulación... pero en modo tutorial está ok.
	public Set getProductos(){
		return this.productos;
	}
}
public class Producto {
	private String  codigo;
	private Integer unidades;
				
	public Pedido(){}
				
	// los getters, setters, hashCode, equals,..			
}

Ahora haz clic en cada uno de los botones del formulario HTML, de izquierda a derecha tendríamos:

Con serialize()

Simplemente ejecutamos en javascript (uso jquery para escribir menos) $("#pedidoForm").serialize() para serializar el formulario de la manera tradicional, es decir no es JSON sino la queryString de los parámetros.

pedidoCodigo=CPE1&pedidoDescripcion=Descripci%C3%B3n+Pedido&productoCodigo=CP1&productoUnidades=4&productoCodigo=CP2&productoUnidades=4

Con serializeObject()

Ejecutamos en JavaScript (uso jQuery y JSON) JSON.stringify($("#pedidoForm").serializeObject())

  • JSON.stringify() » Es una función de la librería JSON que convierte a string un objeto JSON.
  • $("#pedidoForm").serializeObject() » Es una función de la librería JSON que construye un JSON con los datos de un formulario.

Si observas bien, semánticamente es mejorable, pues genera un JSON:

{«pedidoCodigo»:»CPE1″,»pedidoDescripcion»:»Descripción Pedido»,
«productoCodigo»:[«CP1″,»CP2″],»productoUnidades»:[«4″,»4»]}

Es más correcto semánticamente:

{«codigo»:»CPE1″,»descripcion»:»Descripción Pedido»,
«productos»:[{«codigo»:»CP1″,»unidades»:»4″},{«codigo»:»CP2″,»unidades»:»4″}]}

Además usando esta segunda serialización, podremos usar de manera más directa librerías como Jackson así como las anotaciones @ResponseBody y @RequestBody de Spring MVC para deserializar automáticamente a objetos JAVA en la parte servidora

¿Cómo construyo ese JSON?

Construcción del JSON personalizado

Para crear el JSON vamos a crear objetos JavaScript con sus atributos y métodos. Posteriormente lo serializaremos a JSON con las funciones estándar de JavaScript.

var Producto = function(codigo, unidades){
   this.codigo	 = codigo;
   this.unidades = unidades;
}
var Pedido = function(codigo, descripcion){
   this.codigo		= codigo;
   this.descripcion	= descripcion;
   this.productos  = new Array();
}
Pedido.prototype.addProducto = function(prod){
   this.productos.push(prod);
}
Pedido.prototype.getProductos = function(){
   return this.productos;
}

Y para crear el JSON personalizado usamos un poco de JQuery para escribir menos:

function getFormJson(){
	var pedidoObj    = new Pedido($('#pedidoCodigo').val(), $('#pedidoDescripcion').val());
	var prodCodigos  = $("input[name='productoCodigo']");
	var prodUnidades = $("input[name='productoUnidades']");
	
	jQuery.each(prodCodigos, function(pos, item){
		pedidoObj.addProducto(new Producto(prodCodigos[pos].value, prodUnidades[pos].value));
	});
	
	return pedidoObj;
};

Si lo que deseas además es modificar la vista con los datos devuelvos por el servidor en una petición ejecutada via Ajax, puedes hacer cosas como:

function loadPedido(){
	$.ajax({
	  	url: 'Una URL de tu proyecto que retorne un JSON',
	  	type: 'GET',
	  	contentType: "application/json",
	  	success: function(jsonObj) { 
		  	$("#pedidoCodigo").val(jsonObj["codigo"]);
			  	$("#pedidoDescripcion").val(jsonObj["descripcion"]);
			}
	});		
}

Conclusiones

Conocer bien todas las tecnologías disponibles y saber en que tipo de proyectos en encajan es extremadamente importante, pues de esa decisión y conocimientos depende el éxito del desarrollo.

Usando arquitecturas ligeras como la expuesta en este artículo, puede hacer un tiempo de desarrollo algo más elevado respecto a otras tecnologías (JSF con primefaces por ejemplo) pero desde luego el sistema es bastante escalable debido al bajo uso de CPU del servidor y el aprovechamiento de los recursos del cliente.

Espero os haya parecido interesante, un saludo.
Carlos García.

5 COMENTARIOS

  1. en el código
    \\\»jQuery.each(prodCodigos, function(pos, item){
    pedidoObj.addProducto(new Producto(prodCodigos[pos].value, prodUnidades[pos].value));
    }); \\\»
    Cual es la funcion de \\\»item\\\»?????

  2. Buena observación 🙂

    Efectivamente \\\»item\\\» es para cada vuelta del bucle exactamente lo mismo que \\\»prodCodigos[pos]\\\», por lo que podríamos sustituirlo y quedaría un código un poco más pequeño.

    Saludos

  3. Cuando intento programar esto en un fichero .JS me dice que las palabras reservas public o private solo se pueden usar en un archivo .ts.

    Me has gustado mucho tie explicacion pero no se como implementarlo en un codigo exclusivamente n javascript.

    Gracias

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