jueves, 22 de mayo de 2014

Consumiendo servicios JSON de Liferay usando Jersey

Consumiendo servicios JSON de Liferay usando Jersey
Liferay viene con servicios RESTful llamados "Servicios Web JSON", porque utiliza el formato JSON. En este post voy a compartir una manera de consumir desde Jersey para acceder a sus datos.

¿Cómo sabemos qué servicios disponemos en nuestro liferay? Solo basta con entrar a la dirección http://host:puerto/api/jsonws/

Pero, por seguridad, necesitamos primero iniciar sesión en nuestro servidor. Así fue configurado.

Además, si nosotros creamos nuestros propios portlet con Service Builder, los servicios allí definidos también estarán publicados.

Ahora bien, si lo que queremos es usar los servicios JSON desde otra aplicación java, usaremos un par de bibliotecas necesarias. La primera será jersey-client.

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.6</version>
        </dependency>


Para nuestro ejemplo, probaremos leer todos los grupos que están registrados en el servidor.Para ello necesitamos el id de compañía, y el URL donde está el servicio

    static final String URL = "http://localhost:8080"; //el host
    static final String JSONWS_URL = URL + "/api/jsonws"; //la ruta de los servicios
    static final String GET_GROUPS_URL = JSONWS_URL + "/group/get-groups"; //la ruta del servicio de grupos
    static final int COMPANY_ID = 9999; //el id de compañia
    static final String USER = "usuario", PASS = "pass"; //las credenciales


La autenticación se implementará de manera Basic, pero en la cabecera (no encontré otra manera efectiva).
        String passEnc = Base64.encodeAsString(USER + ':' + PASS);
        Client groupsClient = ClientBuilder.newClient();
        WebTarget target = groupsClient.target(GET_GROUPS_URL + "/company-id/" + COMPANY_ID + "/parent-group-id/0/site/true"); //esta es la ruta para el servicio de obtener todos los grupos
        Invocation.Builder invocationBuilder = target.request()
                .header("Authorization", "Basic " + passEnc); //inicia la autenticacion
        Response response = invocationBuilder.get(); //haciendo GET al URL
        if (response.getStatus() == Response.Status.OK.getStatusCode()) { //si se conecto correctamente...

            String resp = response.readEntity(String.class); //... entonces recibo la cadena..
            LOG.log(Level.INFO, "response.getEntity():{0}", resp); //.. y ya tengo la lista

        }



Pero, como podrán ver, solo hemos obtenido una cadena. Créame que traté de jalarlo como un objeto ya proceso usando el Unmarshall propio de Jersey, pero no tuve éxito. Así que me ayudé usando el Gson de Google.
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.2.4</version>
        </dependency>

Y, como debo obtener un arreglo de objetos, hago lo siguiente:
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
Type listType = new TypeToken<ArrayList<Group>>() {
}.getType();

List<Group> groups = gson.fromJson(resp, listType); //convierto la cadena "resp" en lista de objetos



Y, mi clase Group tiene la siguiente estructura:
public class Group {
    private boolean active;
    private int groupId;
    private String name;
// más propiedades
// ... y setters y getters


Como saber servicios disponibles

Para conocer los servicios Json disponibles, bastará con revisar la lista mencionada arriba, tomar uno de ellos y probar sus ejemplos. Con ello sabremos cómo llamar a sus parámetros.

Probando la llamada del servicio get-groups con algunos parámetros


... y revisando la llamada tipo GET por URL que debería usarse con esos parámetros.


Espero que les sea de utilidad, si algún momento quieren consumir los servicios json de liferay desde una aplicación que no sea liferay.

Buen día para todos!