Google Web Toolkit. Небольшое руководство

1. Введение.

1.1. Презентация
Я написал это небольшое руководство для людей, которые хотят научится создавать динамические приложения пользуясь GWT (Google Web Toolkit) в AMP (Apache MySQL PHP) среде. Основная идея в том, чтобы написать небольшой и очень простое приложение с использованием PHP и MySQL на стороне сервера, GWT для реализации интерфейса, JSON для обмена данными между клиентской и северной частями.

1.2. О JSON
JSON (JavaScript Object Notation) - это легкий и удобный формат обмена данными. Отличительной чертой является то, что он прост и понятен для человека. Этот формат легко обрабатывается и генерируется программами. Он основан на языке JavaScript, Standard ECMA-262 3rd Edition — December 1999. JSON — это текстовый формат, не зависящий от языка программирования. JSON использует соглашения близкие к Си-подобным языкам, включая C, C++, C#, Java, JavaScript, Perl, Python, и много других. Все это делает JSON идеальным языком для обмена данными. Вы можете найти много полезной информации о JSON здесь www.json.org (и тут: ru.wikipedia.org/wiki/JSON)

1.3. О GWT
GWT (Google Web Toolkit) - это инструмент позволяющий легко создавать AJAX (ru.wikipedia.org/wiki/AJAX) приложения на языке JAVA, проще говоря, GWT “переводит” ваш JAVA код в HTML и JavaScript. Подробнее о GWT можно прочесть по адресу http://code.google.com/webtoolkit/

1.4. Об этом руководстве
Мы сделаем небольшое приложение для поиска информации по сотрудникам в базе данных MySQL, используя в качестве параметра поиска имя сотрудника.

2. Работа над серверной частью.

2.1. База данных
Нам нужна всего одна таблица, которая будет называться ‘directory’, и которую мы заполним информацией о сотрудниках:

2.2. PHP скрипт
Для доступа к данным базы напишем PHP скрипт. Он будет выбирать данные и преобразовывать в JSON формат. Для этого будем использовать JSON PHP class, который можно скачать отсюда http://pear.php.net/pepr/pepr-proposal-show.php?id=198. Этот класс позволяет преобразовывать значения из PHP в JSON формат и отправлять их браузеру. Файл ‘index.php’ будет содержать следующий код:

1.
 < ?
 2.
 
 3.
 // вызов JSON.php
 4.
 require_once(”JSON.php”);
 5.
 
 6.
 // коннект к базе
 7.
 
 8.
 $conector = mysql_connect(’localhost’, ‘root’, ‘juan’) or die(mysql_error());
 9.
 mysql_select_db(’JSONPHP’) or die(mysql_error());
 10.
 
 11.
 //формируем запрос
 12.
 
 13.
 $sqlQuery = “SELECT * FROM directory WHERE name LIKE ‘”. $_REQUEST[’tosearch’]. “%’”;
 14.
 $dataReturned = mysql_query($sqlQuery) or die(mysql_error());
 15.
 $i = 0;
 16.
 
 17.
 while($row = mysql_fetch_array($dataReturned)){
 18.
 
 19.
 // заполняем массив $value данными.
 20.
 
 21.
 $value{”item”}{$i}{”Employe Number”}= $row[’enumber’];
 22.
 $value{”item”}{$i}{”Name”}= $row[’name’];
 23.
 $value{”item”}{$i}{”Position”}= $row[’position’];
 24.
 $value{”item”}{$i}{”Phone Number”}= $row[’phnumber’];
 25.
 $value{”item”}{$i}{”Location”}= $row[’location’];
 26.
 $i++;
 27.
 }
 28.
 
 29.
 // использую JSON.php конвертируем данные в JSON формат и отправляем в браузер
 30.
 
 31.
 $json = new Services_JSON();
 32.
 $output = $json->encode($value);
 33.
 print($output);
 34.
 ?>

И это весь код. Вывод этого php скрипта должен быть похож на следующие:
{”item”:[{
“Employe Number”:”110009″,
“Name”:”Juan Hurtado”,
“Position”:”System Analist”,
“Phone Number”:”81001121″,
“Location”:”Monterrey City”}]
}

Теперь пора заняться интерфейсом и GWT.

3. Работа над клиентской частью.

3.1 Пример с JSON RPC
На сайте http://code.google.com/webtoolkit/ есть несколько примеров использования GWT. Один из них показывает, как использовать GWT в связке с JSON для доступа к сервису Yahoo. Мы возьмем за основу нашего интерфейса пример JSON RPC.

3.2 Создание нового приложения
Используя projectCreator.cmd (этот файл находится в дистрибутиве GWT) создадим новый проект:

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

Теперь создадим новый проект для eclipse с помощью applicationCreator.cmd:

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

Created directory PHPJSONsrccomjuan
Created directory PHPJSONsrccomjuanclient
Created directory PHPJSONsrccomjuanpublic
Created file PHPJSONsrccomjuanPHPJSON.gwt.xml
Created file PHPJSONsrccomjuanpublicPHPJSON.html
Created file PHPJSONsrccomjuanclientPHPJSON.java
Created file PHPJSONPHPJSON.launch
Created file PHPJSONPHPJSON-shell.cmd
Created file PHPJSONPHPJSON-compile.cmd

Пример JSON RPC содержит классы, которые позволяют обрабатывать иформацию в формате JSON. (Тут говорится о старой версии примера JSON RPC; в новой версии примера JSON RPC эти файлы не идут в дистрибутиве примера, так как эти классы стали стандартными в новой версии GWT. Но никто не мешает вам следовать примеру, все это будет работать и с новой версией GWT) Скопируем из примера следующие файлы в папку PHPJSONsrccomjuanclient:

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

Во всех файлах нужно заменить строчку с данными о пути пакета. (в нашем случае нужно заменить package com.google.gwt.sample.json.client; на package com.juan.client;) Также исправьте пути в файле JSONParser.java. Затем импортируем наш проект в Eclipse как написано в документации по GWT. Запустите Eclipse и кликните в меню File -> Import. В появившемся окне выберите пункт ‘Existing Projects into Workspace’, укажите путь к файлу .project в следующем окне. После этого вы должны увидеть ваш GWT проект:

Работа над клиентской частью.

Создадим класс JSONRequester и опишем следующие метод:

1.
 public Widget initializeMainForm() {
 2.
 /*
 3.
 * Иницилизация и установка панели, которая будет содержать
 4.
 * поисковую форму и вывод результата
 5.
 */
 6.
 
 7.
 FocusPanel fpn = new FocusPanel();
 8.
 Grid gd = new Grid(1,2);
 9.
 
 10.
 b1.setText(”Search”);
 11.
 b1.addClickListener(new SearchButtonClickListener());
 12.
 
 13.
 gd.setWidget(0, 0, txtBox);
 14.
 gd.setWidget(0, 1, b1);
 15.
 
 16.
 gdOut.setWidget(0,0,gd);
 17.
 
 18.
 gdOut.setBorderWidth(1);
 19.
 gdOut.setWidth(”500px”);
 20.
 
 21.
 childGrid.setCellPadding(0);
 22.
 childGrid.setCellSpacing(0);
 23.
 childGrid.setWidth(”490px”);
 24.
 
 25.
 fpn.add(gdOut);
 26.
 
 27.
 return fpn;
 28.
 }

Как вы видете создается элемент FocusPanel, затем мы прикрепляем эелемент Grid(Сетка), на этой сетке располагаем все нужные элементы. В обработчике клика по кнопке создается класс SearchButtonClickListener, которые будет содержать следующие строки:

1.
 private class SearchButtonClickListener implements ClickListener {
 2.
 
 3.
 public void onClick(Widget sender) {
 4.
 /*
 5.
 * Когда пользователь нажимает кнопку мы получаем URL.
 6.
 */
 7.
 itemNumber = 0;
 8.
 doFetchURL();
 9.
 }
 10.
 
 11.
 private void doFetchURL() {
 12.
 /*
 13.
 * Получаем URL и вызываем обработчик
 14.
 */
 15.
 b1.setText(”Searching …”);
 16.
 if (!HTTPRequest.asyncGet(DEFAULT_SEARCH_URL + “?tosearch=” + txtBox.getText(),
 17.
 
 18.
 new JSONResponseTextHandler())) {
 19.
 
 20.
 b1.setText(”Search”);
 21.
 }
 22.
 }
 23.
 }

Этот класс содержит метод doFetchURL(), с помощью которого находится URL и вызывается класс JSONResponseTextHandler() для выполнения операций над JSON документом:

1.
 private class JSONResponseTextHandler implements ResponseTextHandler {
 2.
 
 3.
 public void onCompletion(String responseText) {
 4.
 /*
 5.
 * После того, как полученны данные в формате JSON мы
 6.
 * обрабатываем их и выводим результат
 7.
 */
 8.
 
 9.
 JSONObject jsonObject;
 10.
 try {
 11.
 jsonObject = JSONParser.parse(responseText);
 12.
 displayJSONObject(jsonObject);
 13.
 
 14.
 } catch (JSONException e) {
 15.
 
 16.
 }
 17.
 
 18.
 b1.setText(”Search”);
 19.
 
 20.
 }
 21.
 
 22.
 private void displayJSONObject(JSONObject jsonObject) {
 23.
 /*
 24.
 * Очищаем Grid(сетку) и заполняем новыми результатами
 25.
 */
 26.
 
 27.
 childGrid.clear();
 28.
 requestChildrenGrid(jsonObject);
 29.
 gdOut.setWidget(1,0,childGrid);
 30.
 
 31.
 }
 32.
 
 33.
 private void requestChildrenGrid(JSONValue jsonValue){
 34.
 /*
 35.
 * Заполнение Grid(сетки)
 36.
 */
 37.
 
 38.
 JSONObject jsonObject;
 39.
 if(jsonValue.isArray() != null){
 40.
 for(int i = 0; i < jsonValue.isArray().size();i++){
 41.
 requestChildrenGrid(jsonValue.isArray().get(i));
 42.
 childGrid.setWidget(itemNumber,0,new HTML(”<HR/>”));
 43.
 childGrid.setWidget(itemNumber,1,new HTML(”<hr />”));
 44.
 
 45.
 itemNumber++;
 46.
 int resizeNumber = itemNumber + 1;
 47.
 childGrid.resize(resizeNumber,2);
 48.
 }
 49.
 } else {
 50.
 
 51.
 if ((jsonObject = jsonValue.isObject()) != null) {
 52.
 String[] keys = jsonObject.getKeys();
 53.
 
 54.
 for (int i = 0; i < keys.length; ++i) {
 55.
 String key = keys[i];
 56.
 childGrid.setWidget(itemNumber,0,new HTML(”<B>”+ key +”:”));
 57.
 childGrid.setWidget(itemNumber,1,new HTML(jsonObject.get(key).toString()));
 58.
 requestChildrenGrid(jsonObject.get(key));
 59.
 
 60.
 itemNumber++;
 61.
 int resizeNumber = itemNumber + 1;
 62.
 childGrid.resize(resizeNumber,2);
 63.
 }
 64.
 } else if (jsonValue != null) {
 65.
 //
 66.
 
 67.
 } else {
 68.
 //
 69.
 }
 70.
 
 71.
 }
 72.
 }
 73.
 
 74.
 }

Все эти методы из файла JSON.java гугловкого примера JSON RPC. Метод requestChildrenGrid(JSONValue jsonValue) разбивает JSON документ на ключи и значения, ключи обрамляются тэгами “<B>”и прикрепляются к Grid(сетке), которая в свою очередь прикрепляется к FocusPanel. И наконец, в файле PHPJSON.java мы выводим результат на главную панель:

1.
 public void onModuleLoad() {
 2.
 /*
 3.
 * Для красоты используем TabPanel
 4.
 */
 5.
 TabPanel tp = new TabPanel();
 6.
 JSONRequester myJson = new JSONRequester();
 7.
 
 8.
 tp.add(myJson.initializeMainForm() ,”Corporate Directory”);
 9.
 
 10.
 tp.selectTab(0);
 11.
 
 12.
 RootPanel.get().add(tp);
 13.
 }

Вот как должно выглядеть приложение в результате:

Работа над клиентской частью. - 2