lunes, 1 de diciembre de 2014

J2ME Tutorial Parte V

Programación en red en MIDP

 OBJETIVOS

En la clase de hoy vamos a ver el soporte que da MIDP a la programación en red. Como hemos visto en la clase teórica, en el CLDC de J2ME se rediseñaron las clases para entrada/salida y para el soporte a conexiones de red de J2SE, definiendo lo que se denomina CLDC Generic Connection Framework.

CLDC Generic Connection Framework define una serie de interfaces para dar soporte a la variedad de tipos de conexiones que nos podemos encontrar en dispositivos móviles, pero no implementa ninguna de ellas, es en los perfiles donde se debe realizar esta implementación. En el perfil con el que estamos trabajando, MIDP, se debe dar soporte obligatoriamente a conexiones HTTP, a través de la implementación del interfaz HttpConnection.

Para la práctica final no necesitais hacer uso de conexiones de red, por lo que es muy recomendable realizar esta práctica para que completeis vuestros conocimientos sobre MIDP.


 CLDC Generic Connection Framework
En el CLDC Generic Connection Framework, todas las conexiones se crean utilizando el método estático open de la clase Connector. Si no se produce ningún error, este método devuelve un objeto que implementa una de las interfaces definidas en el CLDC Generic Connection Framework.

Estas interfaces están contenidas en el paquete javax.microedition.io y son:

  • El interfaz Connection es el tipo básico de conexión. Esta conexión sólo puede abrirse y cerrarse.

  • El interfaz InputConnection representa un dispositivo desde el que se pueden leer datos. Proporciona el método openInputStream que devuelve un stream de entrada para la conexión.

  • El interfaz OuputConnection representa un dispositivo en el que se pueden escribir datos. Proporciona el método openOutputStream que devuelve un stream de salida para la conexión.

  • El interfaz StreamConnection que combina la conexiones de entrada y de salida anteriores.

  • El interfaz ContectConnection que es una subinterfaz de StreamConnection. Proporciona acceso a información de algunos meta datos proporcionados en un conexión HTTP.

  • El interfaz StreamConnectionNotified que espera a que se establezca una conexión. Devuelve un StreamConnection a través del cual puede establecerse un enlace de comunicación bidireccional.

  • El interfaz DatagramConnection que representa el destino de un datagrama.

El método open de la clase Connector tiene la siguiente sintaxis,
Connector.open(String);

donde el parámtero String tiene el formato "protocol:address;parameters". Por ejemplo:
  • Conexión HTTP:
    Connector.open("http://www.it.uc3m.es/pervasive");
    
  • Conexión Datagrama:
    Connector.open("datagram://address:port#");
    
  • Conmunicación con puerto serie:
    Connector.open("comm:0;baudrate=9600");
    
  • Acceso a ficheros:
    Connector.open("file:/miFichero.txt");
    

El objetivo de tener esta sintaxis, es abstraer al programador de las diferencias que existen entre los diferentes protocolos, de manera que la mayoría del código de una aplicación no se modifica cuando se cambia el protocolo que se está usando.

IMPORTANTE: Los ejemplos de conexiones anteriores son sólo ilustrativos. CLDC en sí mismo no proporciona ninguna implementación de ningún protocolo, éstas deben de proporcionarse a nivel de perfil. Además un determinado perfil no tiene porque implementar todos los protocolos, así MIDP proporciona una implementación del protocolo HTTP, pero en general no implementa ni sockets, ni datagramas (aunque algunos fabricantes pueden incorporarlas).

En el siguiente apartado veremos el interfaz HttpConnection propocionada en MIDP.


 HttpConnection
HTTP puede implementarse utilizando protocolos IP (como TCP/IP) o protocolos no-IP (como WAP o i-mode), por este motivo se seleccionó como protocolo para comunicaciones de red en MIDP. Todas las implementaciones de MIDP deben soportarlo, garantizando de esta manera la portabilidad de las aplicaciones, que utilizan este protocolo, entre diferentes dispositivos.

En MIDP se define un nuevo interfaz dentro de la jerarquía del CLDC Generic Connection Framework, el interfaz HttpConnection para el soporte a conexiones HTTP. Este interfaz extiende del interfaz ContentConnection.

El protocolo HTTP es un protocolo a nivel de aplicación del tipo petición/respuesta, en el que los parámetros de una petición deben establecerse antes de que se envíe la petición. La conexión puede estar en uno de los siguientes tres posibles estados:
  • "Setup": No se ha establecido todavía la conexión.

  • "Connected": Se ha establecido la conexión, la petición se ha enviado y se está esperando por una respuesta.

  • "Closed": La conexión se ha cerrado.
En el interfaz HttpConnection se proporcionan una serie de métodos que pueden invocarse en cada uno de los estados anteriores:

En el estado "setup" se pueden invocar los siguientes métodos:

  • setRequestMethod(String method) que establece el método de la petición, que puede ser POST, GET o HEAD. El método por defecto es GET y si el método no es HTTP o la implementación de HTTP está recortada y no lo soporta, se produce una IOException.

  • setRequestProperty(String key, String value) que permite indicar el valor de algunas propiedades HTTP antes de enviar la petición, la propiedad que se quiere establecer se indica en el parámetro key y su valor se establece en el parámetro value.
Por ejemplo, en el código siguiente se crea una conexión HTTP a la URL http://www.it.uc3m.es/pervasive y se indica que el método de la petición es POST, y que la propiedad HTTP User-Agent tiene el valor Profile/MIDP-1.0 Configuration/CLDC-1.0:
HttpConnection c = (HttpConnection)Connector.open("http://www.it.uc3m.es/pervasive");
c.setRequestMethod(HttpConnection.POST);
c.setRequestProperty("User-Agent, "Profile/MIDP-1.0 Configuration/CLDC-1.0");

La transición entre el estado "setup" y el estado "connected" se produce cuando se invoca algún método que precisa enviar o recibir datos al servidor con el que se establece la conexión. Algunos de los métodos que proporciona la implementación del interfaz HttpConnection y que provocan esta transición, son:
Cuando la conexión está abierta (se ha pasado al estado de "connected"), se pueden invocar los siguientes métodos:

A continuación se muestra un ejemplo de código en el que se utiliza la implementación de HttpConnection para leer el contenido de la página http://www.it.uc3m.es/celeste/docencia/cr/hola.txt y mostrarselo al usuario (MIDletHTTPExample.java):

import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;

/**
 * Un ejemplo de MIDlet para visualizar el contenido de una URL
 * utilizando la implementación del interfaz HttpConnection.
 */

public class MIDletHTTPExample extends MIDlet {

  private Display display;
  private String url = "http://www.it.uc3m.es/celeste/docencia/cr/hola.txt";

  public MIDletHTTPExample() {
    display = Display.getDisplay(this);
  }

  /**
   * Método startApp()
   */
  public void startApp() {
    // Llama al método download para descargar el contenido de la URL
    try {
      download(url);
    } catch(IOException e) {
      System.out.println("IOException: " + e);
    }
  }

  private void download (String url) throws IOException {
    StringBuffer b = new StringBuffer();
    InputStream is = null;
    HttpConnection c = null;
    TextBox t = null;
 
    try {
      long len = 0 ;
      int ch = 0;

      // Abre una conexión del tipo HttpConnection
      c = (HttpConnection)Connector.open(url);
      
      // Obtiene un stream de entrada, para leer el contenido de la url
      // con la que establece la conexión
      is = c.openInputStream();
      
      // Lee hasta que se cierra la conexión
      while ((ch = is.read()) != -1) {
        b.append((char)ch);
      }
      
      // Se contruye un TextBox con el contenido de la URL
      t = new TextBox("Hola...", b.toString(), 1024, 0);

    } finally {
      // Se cierra tanto el stream de entrada
      if (is != null)
        is.close();
      // Se cierra la conexión
      if (c != null) 
        c.close();
    }  
    
    // Se visualiza el TextBox en el Display
    display.setCurrent(t);
  }
  
   /**
    * pauseApp
    */
   public void pauseApp() {
   }

   /**
    * destroyApp
    */
   public void destroyApp(boolean unconditional) {
   }
}

Ejercicio 1:Partiendo del código del ejemplo anterior realizad un MIDlet que solicite al usuario una URL y una etiqueta HTML, y le muestre como resultado el texto modificado por esa etiqueta.

Ejercicio 2:Repetid el ejercicio anterior, pero además de visualizar el texto modificado por la etiqueta HTML, almacenad su contenido en un Record Store, de forma que el usuario de forma "off-line" pueda visualizar el resultado de sus consultas (por lo tanto, se debe de almacenar: URL solicitada, etiqueta HTML indicada y texto modificado por la etiqueta HTML en la URL indicada).

No hay comentarios.:

Publicar un comentario