jueves, 6 de abril de 2017

Un vistazo a JSON-B de Java EE8

Java EE 8 viene con muchas características interesantes, y en este post veremos un poco de la nueva implementación: JSON Binding, o también conocido como JSON-B (JSR-367)

Ya tenenemos un JSON-P para manipular y procesar JSON (lo hemos visto en un post anterior: Ejemplo básico de API JSON e Java EE7 ) pero usarlo quizás no sea tan cómodo como es Gson o Jackson.

Java EE necesita de un estándar propio, por eso se encargaron de desarrollar el JSR-367 que consiste en procesar de Java a JSON y viceversa de manera muy transparente.

Implementación


Está disponible una implementación muy madura para esta especificación. Se encuentra en http://json-b.net. Para usarlo en nuestro proyecto, necesitamos agregar estos repositorios en el pmo.xml
        <repository>
            <id>java.net-Public</id>
            <name>Maven Java Net Snapshots and Releases</name>
            <url>https://maven.java.net/content/groups/public/</url>
        </repository>
        <repository>
            <id>yasson-snapshots</id>
            <name>Yasson Snapshots repository</name>
            <url>https://repo.eclipse.org/content/repositories/yasson-snapshots</url>
        </repository>

Y consideramos estas dependencias:
        <dependency>
            <groupId>javax.json.bind</groupId>
            <artifactId>javax.json.bind-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse</groupId>
            <artifactId>yasson</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>1.1.0-SNAPSHOT</version>
        </dependency>

Con esta configuración, comenzamos nuestro ejemplo.

El objeto

Comenzaremos con definir nuestro objeto, que es un Java Bean común y silvestre:

Luego, comenzaremos por crear nuestro procesador de JSON:
Jsonb jsonb = JsonbBuilder.create();


Listo, no necesitamos nada más. Ahora continuaremos con el procesamiento.

Objeto a JSON

        //Convirtiendo objeto a JSON
        Persona p = new Persona(1, "Diego");
        String obj2json = jsonb.toJson(p);
        System.out.println("json:" + obj2json);


Y el resultado es
json:{"activo":false,"id":1,"nombre":"Diego"}

JSON a Objeto

        //Convirtiendo JSON a Objeto
        String json = "{\"id\":10, \"nombre\":\"java\", \"fechaNacimiento\":\"1976-03-27T00:00:00\", \"activo\":true }";
        Persona q = jsonb.fromJson(json, Persona.class);
        System.out.println("objeto:" + q);


Notar como se pasan las fechas, y que los nombres de los atributos están entre comillas simples.

El resultado es
objeto:Persona{id=10, nombre=java, fechaNacimiento=Sat Mar 27 00:00:00 COT 1976, activo=true}

Lista de objetos a JSON

        //Convirtiendo Lista a JSON
        List<Persona> lista = Arrays.asList(p, q);
        String listaStr = jsonb.toJson(lista);
        System.out.println("Lista json:" + listaStr);


La salida es:
Lista json:[{"activo":false,"id":1,"nombre":"Diego"},{"activo":true,"fechaNacimiento":"1976-03-27T00:00:00","id":10,"nombre":"java"}]

JSON a Lista de objetos

        //Convirtiendo JSON a Lista
        String listaJson = "[{\"id\":1,\"nombre\":\"Ana\"},{\"id\":2,\"nombre\":\"Beto\",\"activo\":true},{\"id\":3,\"nombre\":\"Carlos\",\"fechaNacimiento\":\"2000-05-06T00:00:00\"}]";
        List<Persona> personas = jsonb.fromJson(listaJson, new ArrayList<Persona>() {
        }.getClass());
        System.out.println("Personas:" + personas);



Y el resultado es:

Personas:[{id=1, nombre=Ana}, {id=2, nombre=Beto, activo=true}, {fechaNacimiento=2000-05-06T00:00:00, id=3, nombre=Carlos}]

Personalizando el JSON

Adicionalmente este API puede ser personalizado, aquí un par de muestras:
        //Personalizado el JSONP
        JsonbConfig config = new JsonbConfig() 
                .withFormatting(Boolean.TRUE)    //salidas con formato
                .withDateFormat("dd/MM/yyyy", Locale.getDefault()) //como manejar las fechas
                .withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_DASHES); //otra forma de manipular las propiedades

        Jsonb jsonb2 = JsonbBuilder.create(config);


JSON a Objeto, un poco cambiado:
        String json2 = "{\"id\":10,\"fecha_nacimiento\":\"23/08/1999\" }";
        Persona p2 = jsonb2.fromJson(json2, Persona.class);
        System.out.println("json personalizado:" + p2);


Y esta es la salida:
json personalizado:Persona{id=10, nombre=null, fechaNacimiento=null, activo=false}


Notemos cómo reconoce el nombre de las propiedades entre fecha_nacimiento de JSON con fechaNacimiento de Java, además del formato de fecha.

Y convertir de Objeto a JSON:
        String json3 = jsonb2.toJson(q);
        System.out.println("persona con json personalizado:" + json3);


Y este es el resultado

persona con json personalizado:
{
    "activo":true,
    "fecha-nacimiento":"27/03/1976",
    "id":10,
    "nombre":"java"
}


Luce bonito, no?

Código fuente

No puede faltar el código fuente que usé en este proyecto:

Bibliografía adicional



3 comentarios:

  1. ¿Tiene alguna diferencia/mejora sobre las librerías actuales para manejar jsons?

    ResponderEliminar
    Respuestas
    1. Supongo que esto es solo parte del estandar para los que quieren trabajr explicitamente con Java EE y puedan moverse entre proveedores, pero quien se va a querer cambiar de Hibernate (en el ejemplo de JPA) y quien va a querer moverse de jackson(en este caso).

      Eliminar
  2. Jsonb es de postgresql y es mejor en almacenamiento, herramientas de búsquedas,rendimiento, seguridad, se somete al ACID de una base de datos relacional como garantía de integridad de datos, cosa que aún no posee MongoDB u otra homóloga. El soporte de ésta librería no es un capricho, mucho menos que se quiera sallir de hibernate u otra, se trata que JAVA debe tener soporte sobre un tipo de dato en Postgresql que ha venido evolucionando de tal magnitud que grandes empresas no ven necesario salirse de éste RDBMS para almacenar documentos. Hoy día es tal el éxito de éste tipo de datos y postgresql como almacen, que muchas aplicaciones (de uso intermedio basada en microservicios) construidas en ambientes NODEJS hacen uso de ella, Acaso no es una magnifica noticia que JAVA tenga soporte para éste tipo de innovación, y mas allá, no es acertado que JAVA 8 los soporte?

    ResponderEliminar

Si quieres hacer una pregunta más específica, hazla en los foros que tenemos habilitados en Google Groups


Ah! solo se permiten comentarios de usuarios registrados. Si tienes OpenID, bienvenido! Puedes obtener su OpenID, aquí: http://openid.net/