22 d’octubre 2006

Google toolkit web + PHP

Com alguns ja sabreu estic començant a fer el projecte de final de carrera utilitzen algunes de les eines (Google Toolkit Web) que ens proporciona Google.

Al començament em vaig trobat amb dos problemes importants.

El primer era que no sabia exactament quins eren els objectes que podia posar, per a que servien o quines propietat i limitacions tenien. Una possible solució era aprendrem la API de memòria, però per sort vaig trobar una espècie de IDE per desenvolupar amb GTW (Google Toolkit Web). Aquesta aplicació (
VistaFei) es força util doncs et dona una idea bastant clara del que es pot fer i de les possibilitats que tens.

La segona em va proporcionar grans moments de desesperació. Esta molt be que et donguin una manera de programar en AJAX molt mes senzilla i estructurada però no em serviria de res sinó podia llegir d'una base de dades en temps d’execució.
Una primera aproximació (la mes útil i mes còmode) va ser la que m’oferia
aquesta web on s'explica un dels exemples que et pots descarregar de la web de Google . Es tracte d'utilitzar unes classes anomenades JSON, i que resumint el seu funcionament serveix per passar informació entre dos llenguatges (en aquest cas AJAX i PHP).

Així doncs el primer que s'ha de fer es descarregar-se la classe JSON en PHP. La podeu baixar
d'aqui. La sintaxi es tremendament senzilla. Us dong un exemple:

require_once("JSON.php");
include ("Conexio.php");
$conexio=Conectat();
$busqueda=mysql_query("select * from categories", $conexio);
$i=0;
while ($dades=mysql_fetch_array($busqueda))
{
$vector[$i]=$dades[1];
$i++;
}
mysql_close($conexio);
$json = new Services_JSON();
$output = $json->encode($vector);
print ($output);


Fins aquí tot perfecte, però aquí comença lo mes complicat. Com li diem a GTW que recuperi aquestes dades.

En la pròpia API ja venen incorporades les classes JSON necessàries, per tant no ens haurem de buscar tant la vida.

Per poder capturar les dades que em imprès en el full php, primer de tot accedir al full. Això ho farem mitjançant la funció "HTTPRequest.asyncGet".
Aquesta funció necessita 2 paràmetres. El primer es la URL que ens proporcionarà les dades i l'altre es un objecte d'una classe que implementi la interfície "ResponseTextHandler" que serà el que realment llegirà les dades.

Aquesta interfície t’obligarà a implementar la funció següent:
"public void onCompletion(String responseText)"

Serà cridat automàticament quan es generi l'event al connectar-te a una web. Així doncs en aquesta funció es obligatori escriure (podeu canviar el nom de la variable ;-) ):
"JSONValue jsonValue = JSONParser.parse(responseText);"

Heu de tenir molt en compte que l'objecte de la classe que implementi la interfície anterior, s'ha de crear en la mateixa funció HTTPRequest.asyncGet. Per exemple:

HTTPRequest.asyncGet("
http://192.168.1.3/prova.php", new CapturadorEtiquetes());

Això obliga a tractar les dades recuperades en la mateixa crida onCompletition ja que un cop hagueu sortir del àmbit del objecte haureu perdut tota d’informació. Tampoc servirà guardar-la en una variable externa a la classe ja que passa el mateix.

Així doncs la única sol•lució que he trobat es crear la classe com a classe privada dins la classe on tingueu declarades els widgets que hagi de modificar el ResponseTextHandle i tota manipulació de les dades rebudes del PHP fer-les dins aquesta classe. Això ens obligarà a crear classes diferents depenent dels propòsits que vulguem portar a terme amb les dades obtingudes.

Jo ho he fet així:

Classe Capturador (nomes extend les funcions de ResponseTextHandler i esta feta purament per comoditat)
public abstract class Capturador implements ResponseTextHandler
{

public void onCompletion(String responseText)
{
try
{
JSONValue jsonValue = JSONParser.parse(responseText);
fer(jsonValue);
}
catch (JSONException e)
{

}
}

public String treureComes (String origen)
{
return origen.replace('"',' ').trim();
}

public abstract void fer(JSONValue dades);
}

El que realment ens interessa es que en aquesta classe apart d'implementar "OnCompletition" (per no tenir-ho de fer en les següents classes)obligo a totes les classes que derivin d'aquesta a implementar la funció "fer" que es la que realment farà quelcom amb les dades obtingudes.

Ara, cada vegada que vulguem fer algú diferent amb les dades obtingudes del PHP nomes haurem de crear una classe dins de la principal (on s'implementi EntryPoint ) que implementi de "Capturador" i on nomes haurem d’especificar en la funció "fer" com manipularem les dades.


Espero que tot això us serveix. Si no us queda prou clar, aquí teniu el l'enllaç d'on baixar-vos tot el codi del exemple. Veureu que es força senzill.