Cómo mapear json a objetos Java con Jackson ObjectMapper

28/06/2017Artículo original

Hoy vamos a hablar de cómo usar la librería Jackson para mapear fácilmente un Json a objetos Java.

Declarar dependencia

El primer paso es declarar la dependencia en el proyecto, en éste caso usando maven, en el fichero pom.xml añadimos:

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.4.4</version></dependency>

Hecho esto, ya es posible usar la librería en el proyecto.

Introducción a Jackson

Veamos una guía de uso rápido de jackson. Para los siguientes ejemplos supondremos la siguiente clase:

// Nota: Para atributos públicos, no es necesario usar getters y setters.publicclassMiClase{publicStringnombre;publicintedad;// Nota: Si los campos son private o protected, es obligatorio usar getters y setters.// Es recomendable crear el constructor por defecto}

Supongamos también el siguiente json, almacenado en un fichero mijson.json:

{"nombre":"Alicia","edad":13}

Es necesario crear un ObjectMapper, y lo típico es hacerlo estático para re-utilizarlo a lo largo de la aplicación. Un buen lugar para él sería un clase Constant y declarar el ObjectMapper así:

publicstaticfinalObjectMapperJSON_MAPPER=newObjectMapper();

Json a Objeto Java (Des-Serializar)

Para des-serializar el json y crear el objeto en Java:

MiClaseobjeto=JSON_MAPPER.readValue(newFile("mijson.json",MiClase.class);// oMiClaseobjeto=JSON_MAPPER.readValue(newURL("https://ruta/a/mijson.json",MiClase.class);

Objeto Java a Json (Serializar)

Para realizar el proceso inverso, basta con:

JSON_MAPPER.writeValue(newFile("mijson.json"),objeto);// ó:byte[]jsonBytes=JSON_MAPPER.writeValueAsBytes(objeto);// ó:StringjsonString=JSON_MAPPER.writeValueAsString(objeto);

Generalizar el tipo de objeto a des-serializar

Al trabajar con una API, serializar y des-serializar objetos es una tarea común, una forma de generalizar el proceso puede ser la siguiente.

  Pruebas unitarias de código que accede a base de datos

Supongamos que nuestra api devuelve arrays de objetos, por ejemplo una lista de Personas, una lista de productos etc. El modelo en Java sería el siguiente:

publicclassPersona{privateStringNombre;privateStringApellidos;privateintDNI;publicPersona(){}publicStringgetNombre(){returnNombre;}publicvoidsetNombre(StringNombre){this.Nombre=Nombre;}publicStringgetApellidos(){returnApellidos;}publicvoidsetApellidos(StringApellidos){this.Apellidos=Apellidos;}publicintgetDNI(){returnDNI;}publicvoidsetDNI(intDNI){this.DNI=DNI;}}
publicclassProducto{privateStringNombre;privateStringModelo;privateintprecio;privatefloatvaloracion;publicProducto(){}publicStringgetNombre(){returnNombre;}publicvoidsetNombre(StringNombre){this.Nombre=Nombre;}publicStringgetModelo(){returnModelo;}publicvoidsetModelo(StringModelo){this.Modelo=Modelo;}publicintgetPrecio(){returnprecio;}publicvoidsetPrecio(intprecio){this.precio=precio;}publicfloatgetValoracion(){returnvaloracion;}publicvoidsetValoracion(floatvaloracion){this.valoracion=valoracion;}}

Los arrays en json:

//Personas[{"Nombre":"Bob","Apellidos":"BobBob","DNI":123456789},{"Nombre":"Alice","Apellidos":"Alice","DNI":123456789},{"Nombre":"Foo","Apellidos":"bar","DNI":123456789}]//Productos[{"Nombre":"Tele","Modelo":"modelo1","Precio":120,"Valoracion":2.5},{"Nombre":"Tele2","Modelo":"Modelo2","Precio":150,"Valoracion":5},{"Nombre":"Tele3","Modelo":"Modelo3","Precio":520,"Valoracion":5}]

Con estos datos, queremos des-serializar el json en un ArrayList del tipo de clase que sea, en éste caso ArrayList y ArrayList. La forma NO genérica de hacerlo sería:

ArrayList<Persona>personas=JSON_MAPPER.readValue(newFile("personas.json"),JSON_MAPPER.getTypeFactory().constructCollectionType(ArrayList.class,Persona.class));// Para productosArrayList<Producto>productos=JSON_MAPPER.readValue(newFile("productos.json"),JSON_MAPPER.getTypeFactory().constructCollectionType(ArrayList.class,Producto.class));

Ahora bien, si tenemos más modelos, a parte de Personas y Productos, y normalmente, los json se obtienen mediante la API, vamos a repetir un montón de código. Podríamos crear un método genérico para mapear json a objetos java, como el siguiente:

publicstatic<T>List<T>getList(Stringurl,Class<T>clazz){HttpClientclient=HttpClientBuilder.create().build();HttpGetgetRequest=newHttpGet(url);getRequest.setHeader(HttpHeaders.ACCEPT,MediaType.APPLICATION_JSON);List<T>data=null;HttpResponseresponse;try{response=client.execute(getRequest);data=Constants.JSON_MAPPER.readValue(response.getEntity().getContent(),JSON_MAPPER.getTypeFactory().constructCollectionType(ArrayList.class,clazz));}catch(IOExceptionex){logger.error("Error retrieving "+clazz.getName()+" "+ex.toString());}returndata;}

Éste método se usaría así:

// Para personasArrayList<Persona>personas=getList(URLDELAAPIPARAOBTENERPERSONAS,Persona.class);// Para productosArrayList<Producto>personas=getList(URLDELAAPIPARAOBTENERPRODUCTOS,Producto.class);

Conclusión

La librería Jackson de fasterXML ofrece muchísimas más cosas de las vistas aquí. El uso de anotaciones por ejemplo permite ignorar ciertos valores de un modelo, no permitir nulos etc, para más información visita las referencias.

  4 extensiones de Chrome imprescindibles para ingenieros de machine learning y científicos de datos

Referencias

  TRUCO VS #1: Encuentra cualquier cosa instantáneamente en Visual Studio
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Contiene enlaces a sitios web de terceros con políticas de privacidad ajenas que podrás aceptar o no cuando accedas a ellos. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad