在AMP环境中使用GWT

来源:互联网 发布:python的linux运维开发 编辑:程序博客网 时间:2024/06/09 08:46

1. 简介

 1.1 前言
   

       写下这篇文章是因为考虑到有些用户希望在AMP(Apache,MySQL,PHP)环境中使用GWT(Google Web Toolkit)开发动态应用程序。基本想法是写一个非常简单的小程序,用MySQL和PHP作为服务端,GWT作为客户端开发用户界面,客户端服端之间通过 JSON 进行通讯.

 1.2 关于 JSON
    JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式. 对于人们来说阅读和编写都比较简单。 对于机器来说也比较容易解析和生成.他基于 Javascript编程语言, 标准ECMA-262第三版本 -1999/12. JSON是一种不依赖于特定语言而是使用对程序员比较熟悉的类C语言的惯例的文本类型的格式,包括C, C++, C#, Java, JavaScript, Perl, PHP, Python,和许多其它的语言.你会在下面的地址找到关于JSON的有用信息:
 http://www.json.org

    1.3 关于 GWT 

    GWT(Google Web Toolkit) 是一个帮助开发者使用JAVA语言来撰写AJAX应用程序的工具包,简单的说,GWT将JAVA代码"翻译"为Javascript代码,你会在下面地址找到关于GWT的有用信息:
  http://code.google.com/webtoolkit/

    1.4 关于这份指南.

    我们将要开发一个用来在MySQL数据库中的雇员信息的小程序,用雇员名字作为查询参数.


     2. 服务端的工作.

       
2.1 数据库
      
我们将要使用一个单表的数据库,一个名为'directorio'的表格,我们为表格填充如下信息:


2.2 PHP脚本
        为了能访问数据库内容我们要写一个PHP脚本,我们获取这些信息然后格式化它们为JSON格式.我们使用JSON PHP类来格式化,可以到下面地址去下载:
http://pear.php.net/pepr/pepr-proposal-show.php?id=198.

这个类允许我们将php值转换为JSON格式并发送他们到浏览器. 我们写的脚本名为"index.php",下面是代码:

<?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);
?>


就是上面这些了. 这个脚本的输出如下:

{"item":[{
"Employe Number":"110009",
"Name":"Juan Hurtado",

"Position":"System Analist",
"Phone Number":"81001121",
"Location":"Monterrey City"}]
}

  现在让我们使用GWT来实现客户端的用户界面.
3. 客户端的工作.
3.1 JSON远程过程调用例程.

Google在GWT中提供了一些例子程序,其中一个给我们展示了如何使用GWT和JSON来调用Yahoo的服务. 我们以这个例子为基础来编写我们的界面,最初的Google JSON远程过程调用例程可以到这里下载.
3.2 建立一个新的应用程序.
使用 projectCreator.cmd (包含在GWT里),我们建立了一个新的项目:

 C:/>projectCreator.cmd -eclipse PHPJSON -out PHPJSON
Created directory PHPJSON/src

Created file PHPJSON/.project
Created file PHPJSON/.classpath

 

然后我们使用applicationCreator.cmd 建立一个基于eclipse的新的应用程序 

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

原始的JSON 远程过程调用 附带了解析JSON文档的类, 从例子程序中拷贝下列文件到我们的src/client目录下:
  • JSONArray.java
  • JSONBoolean.java
  • JSONException.java
  • JSONNumber.java
  • JSONObject.java
  • JSONParser.java
  • JSONString.java
  • JSONValue.java
我们需要用这些文件替换所有在我们项目中的文件. 同样我们要修改JSONParser.java文件中的路径(ILcom/juan/client/JSONValue),然后我们将这个项目导入到Eclipse中,就像   GWT documentation 中描述的那样.
 3.3 应用程序的相关工作
我们建立一个名叫 JSONRequester的新类,将下面的方法放到类中:
:

  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;
    }

        正如你看到的,一个Focus Panel被调用,然后我们在Panel中加入Grid,这个Grid包含所有要用的组件,当用户点击按钮时我们调用SearchButtonClickListener类,代码如下:

  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");
        }
   }
   }
  

这个类包含了一个doFetchURL()方法,该方法获取URL地址然后调用JSONResponseTextHandler()类,最后我们开始处理JSON文档.

    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 {
         //
        }

      } 
      }

}  

你会发现所有这些方法都在Google例程 JSON 远程过程调用 中的JSON.java文件中,正如你看到的,JSON文档在方法requestChildrenGrid(JSONValue jsonValue)中被分为索引和值,然后格式化索引为粗体并放到表格里,然后放到放到面板中. 最后我们编辑PHPJSON.java文件并且调用 JSONRequester以将结果放到根面板中

 /**
   * 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);

   
   
    }


  就到这里, 最后的程序界面如下:

     你可以到这里下载所有代码,希望这个小例子对你有用。


____________

Juan Hurtado