Serialización / Deserialización con tipo genérico en Java

La serialización de datos en los sistemas modernos es una tarea que día a día afrontamos los desarrolladores. Serializar y deserializar es un componente inseparable de los sistemas modernos. En esta entrada hablaremos sobre este concepto y construiremos un clase genérica para realizar este proceso.

¿Qué es la serialización?

Empecemos por el concepto, usemos este que hemos traído de la mediawiki y que consideramos correcto:

En ciencias de la computación, la serialización (o marshalling en inglés) consiste en un proceso de codificación de un objeto en un medio de almacenamiento (como puede ser un archivo, o un buffer de memoria) con el fin de transmitirlo a través de una conexión en red como una serie de bytes o en un formato humanamente más legible como XML o JSON, entre otros. La serie de bytes o el formato pueden ser usados para crear un nuevo objeto que es idéntico en todo al original, incluido su estado interno (por tanto, el nuevo objeto es un clon del original). La serialización es un mecanismo ampliamente usado para transportar objetos a través de una red, para hacer persistente un objeto en un archivo o base de datos, o para distribuir objetos idénticos a varias aplicaciones o localizaciones.

La serialización es soportada por la mayoría de los lenguajes de programación de forma nativa o a través de librerías de terceros. En Java en particular la serialización de objetos de formato JSON cuenta con diversas implementaciones, entre ellas:

  • GSon: Es una de las librerías más populares, fue desarrollada por Google y es especialmente eficiente en el proceso de serialización o deserialización de datos pequeños, de hasta unos pocos megas. Es muy común usarla en los desarrollos para Android, pero también en aplicaciones backend se emplea con frecuencia.
  • Jackson: Al igual que GSon tiene gran popularidad entre la comunidad de desarrolladores, es una librería muy versátil con gran cantidad de opciones y gran eficiencia en el proceso de conversión de objetos a JSON y viceversa. Es por defecto la librería que emplea Spring Boot a la vez que incluimos el spring-boot-starter-web. Jackson en procesamiento de datos de gran volumen posee un rendimiento superior a GSon.

Con respecto al rendimiento en archivos grandes y pequeños les recomiendo vean este artículo donde hacen una prueba rendimiento.

El resumen se muestra debajo (las gráficas son del artículo relacionado, nuestro blog reconoce su derecho de autor).

Para archivos de pequeño tamaño
En archivos de gran tamaño

Clase genérica para la serialización – deserialización de objetos

Para nuestra clase genérica vamos a usar Jackson, pero puede ser GSON o cualquier otra librería.

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class GenericMapper {
    private static ObjectMapper mapper = new ObjectMapper();
    private static Logger logger = LoggerFactory.getLogger(GenericMapper.class);
    static <T> String serialize(T object) {
        String data = null;
        try {
            data = mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            logger.error("Error en el proceso de serializacion. Detalles: " + e.getMessage());
        }
        return data;
    }
    static <T> T deserialize(String json, Class<T> type) {
        T data = null;
        try {
            data = mapper.readValue(json, type);
        } catch (IOException e) {
            logger.error("Error en el proceso de deserializacion. Detalles: " + e.getMessage());
        }
        return data;
    }
}

A partir de ahora para serializar o deserializar solo bastará con realizar las siguientes acciones:

// Serializar:
String json = GenericMapper.serialize(MiObjeto);
// Deserializar, por ejemplo a las clase Persona
Persona P = GenericMapper.deserialize(json, Persona.class);

Hemos declarado los métodos estáticos, esto puede hacer pensar a algunos sobre si impacta o no en el rendimiento, para esto recomiendo lean este interesante material sobre el static binding vs dinamic binding y como funciona la JVM, por cierto los métodos estáticos son enlazados en tiempo de compilación.

Esperamos te haya gustado y sido útil el artículo.

Leave a Reply

Your email address will not be published. Required fields are marked *