1. Introducción.

 1.1 Presentación
Pensando en algunas de las dudas que han surgido en el foro de GWT (Google Web Toolkit) acerca de como utilizar el GWT para crear aplicaciones dinamicas en ambientes AMP(Apache,MySQL,PHP) elabore este tutorial. La idea basica sera una pequeña aplicacion desde lo mas basico usando AMP del lado del servidor y GWT . La base de datos sera creada en MySQL y usaremos PHP para acceder a ella, por otro lado desarrollaremos la interfaz del lado del cliente usando el GWT, la comunicacion entre el cliente y el servidor se realizara a travez de JSON.

1.2 Acerca de JSON
JSON(JavaScript Object Notation) es un formato de intercambio de datos ligero, es sencillo de leer para un ser humano y sencillo de leer y generar para una maquina. Esta basado en un subset del lenguaje JavaScript Estandar ECMA-262 3ra Edición Diciembre de 1999. JSON es un formato que es completamente independiente al lenguaje en el que se programe, sin embargo resultara familar a quien programe en alguno de los lenguajes de la familia de 'C' (Por ejemplo C,C++,C#, Java, JavaScript,Perl, Python, PHP y muchos otros). Encontrara mas informacion util acerca de JSON aqui http://www.json.org

1.3 Acerca de GWT
GWT (Google Web Toolkit) es un kit de trabajo que permite crear aplicaciones con AJAX programando desde JAVA. En cierta forma el GWT 'traduce' el codigo JAVA a JavaScript permitiendo crear aplicaciones dinamicas para web compatibles con la mayoria de los navegadores de una forma sencilla. Encontrara mas informacion util acerca de GWT aqui http://code.google.com/webtoolkit/

1.4 Acerca de este tutorial
La aplicación que desarrollaremos sera un pequeño buscador, que nos traera los datos de un empleado de la compañia 'Monterrey' a partir de su nombre.

 

1. Trabajando del lado del servidor.


2.1 La base de datos
Crearemos una base de datos con una sola tabla 'directorio', en esta tabla almacenaremos la informacion correspondiente a los empleados de la empresa como se muestra a continuacion:

 


 

2.2 El script en PHP
Para acceder el contenido de la base de datos usaremos PHP. Extraeremos la informacion y le daremos formato JSON. Para ello usarmos la classe JSON.php la cual puede ser descargada desde http://pear.php.net/pepr/pepr-proposal-show.php?id=198. Esta clase nos permite comvertir valores de PHP a formato JSON para posteriormente ser enviados al cliente a travéz del navegador. Creamos un archivo index.php que servira los documentos JSON. El codigo es como a continuacion se muestra:


<?php


// Here we call JSON.php

require_once("JSON.php");
 
// Then we do the query to the MySQL DB, and fetch the results
 
$conector = mysql_connect('127.0.0.1', 'root', 'juan') or die(mysql_error());
mysql_select_db('JSONPHP') or die(mysql_error());

$sqlQuery = "SELECT * FROM directory WHERE name LIKE '". $_REQUEST['tosearch']. "%'";
$dataReturned = mysql_query($sqlQuery) or die(mysql_error());
$i = 0;
 
while($row = mysql_fetch_array($dataReturned)){
 
// We fill the $value array with the data.
 
 $value{"item"}{$i}{"Employe Number"}= $row['enumber'];
 $value{"item"}{$i}{"Name"}= $row['name'];
 $value{"item"}{$i}{"Position"}= $row['position'];
 $value{"item"}{$i}{"Phone Number"}= $row['phnumber'];
 $value{"item"}{$i}{"Location"}= $row['location'];
 $i++;
}
 
// We use JSON.php for convert the data to JSON format and send it to the browser
 
$json = new Services_JSON();
$output = $json->encode($value);
print($output);
?>


Y con eso finalizamos el trabajo del lado del servidor, la salida se vera mas o menos de la siguiente forma: 

{"item":[{
"Employe Number":"110009",
"Name":"Juan Hurtado",
"Position":"System Analist",
"Phone Number":"81001121",
"Location":"Monterrey City"}]
}

 Vayamos ahora a trabajar en la interfaz del lado del cliente con GWT.

 

3. Trabajando del lado del cliente.

3.1 Tomando JSON RPC como base.

   Google ofrece una serie de ejemplos con el GWT, uno de ellos muestra el uso del GWT con JSON realizando una consulta aun servicio de Yahoo. Tomaremos como base ese ejemplo para realizar nuestra interfaz, el ejemplo JSON RPC puede ser descargado aqui.

 3.2 Creando una nueva nuestra aplicación.

   Usando las herramientas que nos ofrece el GWT creamos un nuevo projecto usando el projectCreator.cmd:

 C:\>projectCreator.cmd -eclipse PHPJSON -out PHPJSON
Created directory PHPJSON\src
Created file PHPJSON\.project
Created file PHPJSON\.classpath

 

 

   Ahora creamos una nueva aplicacion para eclipse usando el applicationCreator.cmd:

 

C:\>applicationCreator.cmd -eclipse PHPJSON -out PHPJSON com.juan.client.PHPJSON

Created directory PHPJSON\src\com\juan
Created directory PHPJSON\src\com\juan\client
Created directory PHPJSON\src\com\juan\public
Created file PHPJSON\src\com\juan\PHPJSON.gwt.xml
Created file PHPJSON\src\com\juan\public\PHPJSON.html
Created file PHPJSON\src\com\juan\client\PHPJSON.java
Created file PHPJSON\PHPJSON.launch
Created file PHPJSON\PHPJSON-shell.cmd
Created file PHPJSON\PHPJSON-compile.cmd

 

               El ejemplo  JSON RPC contiene una serie de classes que nos permiten realizar el parseo del documento JSON, copiamos los siguientes archivos del ejemplo a nuestro directorio "client" dentro de nuestro directorio "src":

  • JSONArray.java
  • JSONBoolean.java
  • JSONException.java
  • JSONNumber.java
  • JSONObject.java
  • JSONParser.java
  • JSONString.java
  • JSONValue.java

         Remplazamos la linea package por la correspondiente a nuestra aplicacion. Tambien sera necesario revisar el archivo JSONParser.java y remplazar las rutas que hacen referencia al ejemplo por las correspondientes en nuestra aplicacion, (por ejemplo ILcom/juan/client/JSONValue). Una vez terminado importamos el proyecto en Eclipse tal como lo indica la documentacion de GWT.

 3.3 Trabajando en nuestra aplicacion.

        Crearemos una nueva clase JSONRequester en ella declaramos la siguiente funcion:

  public Widget initializeMainForm() {
   
    /*
     *  Here we initialize and setup a panel for use it as container for the search form and
     *  the results.
     */
   
    FocusPanel fpn = new FocusPanel();
    Grid gd = new Grid(1,2);
           
    b1.setText("Search");
    b1.addClickListener(new SearchButtonClickListener());
   
    gd.setWidget(0, 0, txtBox);
    gd.setWidget(0, 1, b1);

    gdOut.setWidget(0,0,gd);
   
    gdOut.setBorderWidth(1);
       gdOut.setWidth("500px");
             
       childGrid.setCellPadding(0);
    childGrid.setCellSpacing(0);
    childGrid.setWidth("490px");
   
 
    fpn.add(gdOut);
   
    return fpn;
    }

           

         Como puede observar creamos un Focus Panel y le adjuntamos una Grid que contendra todos los Widgets que usaremos, cuando el usuario da click en el Boton, se llama a la classe SearchButtonClickListener la cual se mustra a continuacion:

  private class SearchButtonClickListener implements ClickListener {
/*
 *  (non-Javadoc)
 * @see com.google.gwt.user.client.ui.ClickListener#

* onClick(com.google.gwt.user.client.ui.Widget)
 */
      public void onClick(Widget sender) {
       /*
        * When the user click the button we fetch the URL.
        */
        itemNumber = 0;
        doFetchURL();
      }

  
   private void doFetchURL() {
      /*
       * Here we fetch the URL and call the handler
       */  
      b1.setText("Searching ...");
        if (!HTTPRequest.asyncGet(DEFAULT_SEARCH_URL + "?tosearch=" + txtBox.getText(),

new JSONResponseTextHandler())) {
    
        b1.setText("Search");
        }
   }
   }
  

           

       Dicha classe contiene el metodo doFetchURL() el cual es el que se encarga de realizar el llamado a la URL de nuestro servidor y llamar a la clase JSONResponseTextHandler() que se manejara el documento::

    private class JSONResponseTextHandler implements ResponseTextHandler {
    /*
     *  (non-Javadoc)
     * @see com.google.gwt.user.client.ResponseTextHandler#onCompletion(java.lang.String)
     */ 
   
    public void onCompletion(String responseText) {
  /*
   *  When the fetch has been completed we parse the JSON response and
   *  display the result
   */ 
    
     JSONObject jsonObject;
        try {
          jsonObject = JSONParser.parse(responseText);
          displayJSONObject(jsonObject);

        } catch (JSONException e) {

        }

          b1.setText("Search");
         
      }
   
      private void displayJSONObject(JSONObject jsonObject) {
      /*
       * Here we clear the grid and fill it with the new values.
       */   
       childGrid.clear();
       requestChildrenGrid(jsonObject);
       gdOut.setWidget(1,0,childGrid);
       
        }
     
      private void requestChildrenGrid(JSONValue jsonValue){
  
       /*
        * Here we fill the grid.
        */         
       
       
      JSONObject jsonObject;
      if(jsonValue.isArray() != null){
       for(int i = 0; i < jsonValue.isArray().size();i++){
       requestChildrenGrid(jsonValue.isArray().get(i));
       childGrid.setWidget(itemNumber,0,new HTML("<HR/>"));
          childGrid.setWidget(itemNumber,1,new HTML("<HR/>"));
         
   
          itemNumber++;
          int resizeNumber = itemNumber + 1;
          childGrid.resize(resizeNumber,2);
       }
      } else {
     
       if ((jsonObject = jsonValue.isObject()) != null) {
          String[] keys = jsonObject.getKeys();
        
          for (int i = 0; i < keys.length; ++i) {
            String key = keys[i];
            childGrid.setWidget(itemNumber,0,new HTML("<B>"+ key  +":</B>"));
            childGrid.setWidget(itemNumber,1,new HTML(jsonObject.get(key).toString()));
            requestChildrenGrid(jsonObject.get(key));
           
            itemNumber++;
            int resizeNumber = itemNumber + 1;
            childGrid.resize(resizeNumber,2);
          }
        } else if (jsonValue != null) {
          // Only JSONObject, and JSONArray do anything special with toString, so
          // it is safe to handle all non-null cases by simply using toString
          //
           
        } else {
         //
        }

      } 
      }

}  

           

      La mayoria de los metodos que implementa esta clase son los mismos que los del archivo JSON.java en el ejemplo JSON RPC . Puede ver que en el metodo requestChildrenGrid(JSONValue jsonValue) que el documento JSON es separado en llaves y valores. A las llaves se las da formato en negrita y posteriormente se adjuntan a una Grid que va ir al nuestro panel. Finalmente editamos el archivo PHPJSON.java (Que se crea automaticamente al crear la aplicacion), para llamar a la clase JSONRequester y adjuntar el panel con el contenido al Root Panel.

 /**
   * This is the entry point method.
   */
   public void onModuleLoad() {

 /*
  * Just for fun we use a TabPanel as layout
  */   
      TabPanel tp = new TabPanel();
   JSONRequester myJson = new JSONRequester();
   

   
   tp.add(myJson.initializeMainForm()  ,"Corporate Directory");

   
   tp.selectTab(0);

   RootPanel.get().add(tp);
   
   
    }

 

         Y eso es todo, una vez compilada la aplicacion se ve como sigue:

      Finalmente puede descargar el codigo completo de aqui. Espero que este ejemplo le ayude a entender un poco como realizar aplicaciones dinamicas con GWT.  Si tiene dudas encontrara util leer la documentación del GWT .

 

Juan Hurtado