注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

神魔破杜梓的叨叨堂

Programming every day!

 
 
 

日志

 
 
 
 

使用Grails集成一个简单的Flex搜索应用程序  

2008-08-06 17:49:32|  分类: My Tech |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

原文来自Flex Developer Center

The Grails framework greatly simplifies the task of building a Java web application. This article illustrates one approach to integrating a Flex application with a Java server application using Grails. The sample application for this article is a simple Flex search application, but the principles shown here still apply for building more complex applications.

While there are many great options available for connecting Flex applications with a server application, for example, LiveCycle Data Services ES or its open source counterpart BlazeDS, the sample application uses a RESTful approach for client-server communication. It is true that using the aforementioned frameworks offer several powerful advantages, but there are benefits to using a XML/RESTful approach that should not automatically be discounted. Chief among these are:

  1. RESTful services are straightforward to implement and maintain.
  2. The server and client applications, respectively, either respond with XML or parse responses sent in XML, freeing them from dependence on any particular platform. Note: Using XML is not required; the approach outlined here could be used with JSON.
  3. No mapping files of any kind are required.
  4. There is less of a learning curve if this is the first experience building a Flex client with a Java server application.

Though this article focuses on Flex with Grails, since it uses a RESTful approach, you could easily use Spring MVC or a non-Java framework, such as Ruby on Rails.

Requirements

To successfully complete this tutorial you will need the following software and files:

Flex Builder 3

Flex 3 SDK

MySql Database

Eclipse 3.3

Grails

Sample files:

The file flex_grails.zip contains the source code for this article. The top level directory of the extracted file is named sources and will be referred to as <SOURCES_DIR> from this point forward. The <SOURCES_DIR> directory contains the following:

  • /flex – the top level directory of the Flex client. To use this with Flex Builder, open Eclipse and then choose File > Import > Existing Project and select <SOURCES_DIR>/flex
  • /flex-grails – the top level directory of the Grails application. Everything is there for a complete Grails application. To use this in Eclipse, open Eclipse and then choose File > Import > Existing Project then select <SOURCES_DIR>/flex-grails. Note: If you decide to import as a project into Eclipse, I suggest installing the Groovy Eclipse Plugin available at http://groovy.codehaus.org/Eclipse+Plugin.
  • /sql – this directory contains files sakila-schema.sql and sakila-data.sql
  • /FlexTasks.groovy – a Gant file that uses the Flex Ant tasks.

Prerequisites:

Prior experience working with Flex Builder to create applications would be helpful. Some experience using the Grails framework would also be helpful, but it is not required. For additional background, see "Creating components and enforcing separation of concerns with Flex." This article builds on the code developed in that article.

Refactoring

The sample application discussed in Creating components and enforcing separation of concerns with Flex asynchronously communicates with the sever application using the HTTPService class. In this article, I am going to use the same approach and the same code, but I will refactor and add a level of abstraction. Specifically I will:

  1. Add an interface, Controller, with one method, search.
  2. Add an implementation of the Controller interface, named HttpController.
  3. Add a class, URLConstants, which simply holds static strings that the controller will use to connect to the server application. This provides the ability to change the connection strings in one place and have those changes propagate throughout the application.
  4. Add the ability to set the fields and labels properties of the SearchResultGrid class as array literals in the SearchPanelView.mxml file, where the SearchResultGrid class is declared, for increased reusability.

The Controller interface will look something like:

public interface Controller {
public void search(searchParams:Object, callback:Function=null);
}

The parameter searchParams is an object literal in the form {key:value, key:value} that contains the parameters of the request. The parameter callback is a function object that will be executed once the response is returned. The implementation class, HttpController will look like the following (not all of its code is shown):

public class HttpController implements Controller{
private _searchService:HTTPService;
public void search(reqParams:Object, callback:Function=null){

_searchService.method="GET";
_searchService.url = URLConstants.SEARCH;
_searchService.resultFormat=HTTPService.RESULT_FORMAT_E4X;
_searchService.addEventListener(ResultEvent.RESULT,onSearchComplete);
_searchService.addEventListener(FaultEvent.FAULT,onError);
var token:AsyncToken = _searchService.send(params)

token.callback=callback
}

The code in the SearchPanel needed to execute the search is reduced to one line:

_controller.search({text:_searchTerm.text},_searchResultGrid.displaySearchResults);

The URLConstants class will look like:

public final class URLConstants {
private static BASE_URL = "/application"
public static SEARCH_URL = BASE_URL+"/search"
}

Over time this class may grow as the application provides access to other services.

Finally, the SearchResultGrid declaration in the SearchPanelView.mxml file will now look like:

<comp:SearchResultGrid id="searchResultGrid" percentWidth="100"
percentHeight="60" resultElementName="film"
fields="{['title','length','price','date']}"
labels="{['Title','Running Time','Rental Rate','Year Released']}" />

What have I gained from this refactoring? In the search component all the details of the HttpService class, specifically how and where the client communicates with the server, are now abstracted into one method call, _controller.search(), but the callback and the processing of the result remains exactly the same. Why the separate interface and implementation? Here are a few reasons:

  1. This allows me to completely abstract from the search component where or how it is getting its information, which means I can change how it connects to the information source with no impact on the search component.
  2. Testing the search component is now much easier. (Testing is not covered here, but it will be in a future segment).
  3. If at some point I want to start taking advantage of Flex remoting frameworks, I can seamlessly plug in BlazeDS at the controller level by creating a new class that implements Controller with no additional impact on the client code.

Dependency Injection

Now that I have abstracted details of the search process, I need to add an instance of type Controller to the SearchComponent class.

First, I add a setter method in the SearchComponent class:

public function set controller(controller:Controller):void 

Then, I add the following line to the SearchComponent.mxml file:

<comp:HttpController id="controller" />

This is a kind of "poor man's dependency injection". Once the Flex application is loaded,

the HttpController object defined above will be automatically be injected into the SearchComponent class via the setter method defined above.

Setting up the Grails project

At this point the refactoring of the Flex search client is complete, and I am ready to build the Grails application. A discussion of how to build a Grails application is beyond the scope of this article. To run the sample application, first follow these steps to set up Grails and MySQL:

  1. After downloading Grails, extract the archive to a directory and set an environment variable GRAILS_HOME pointing to the directory where you extracted Grails. Also add GRAILS_HOME/bin to your path.
  2. If it is not already installed, download and install MySql. This article is based on version 5.0.51a running on a Mac (Leopard). Start the MySql server after installation.
  3. Change to the directory <SOURCES_DIR>/sql, which contains two files, sakila-schema.sql and sakila-data.sql.
  4. From the command line type mysql -u root -p and enter your password when prompted.

    1. To build the sakila database, at the mysql prompt, type SOURCE sakila-schema.sql; and press Enter.
    2. To load the data, at the mysql prompt type SOURCE sakila-data.sql; and press Enter.
    3. At the mysql prompt type GRANT ALL PRIVILEGES ON sakila.* TO 'sa'@'localhost' IDENTIFIED BY 'pass' WITH GRANT OPTION; and press Enter. Then type quit to disconnect from the MySql server.

Grails controller

Now that you know how the Flex client will communicate with the server, let's go over how the Grails application will respond to the Flex client. Fortunately, Grails makes this extremely simple. The file FilmController.groovy in <SOURCES_DIR>/flex-grails/controller has only one method:

    def search = {
def movies = Film.createCriteria().list{like("title","%${params.text}%")}
render(contentType:"text/xml") {
films {
for(i in movies) {
film {
title(i.title)
length(i.length)
rate(i.rate)
date(i.releaseYear)
}
}
}
}
}

This method searches the Film table for titles that contain the text entered by the user. While it's not a great search effort, it works for demonstration purposes. As you examine this code, note the following:

  • The line that reads films { will be the root node of the XML response and is ignored by E4X.
  • film is the parent node for each result returned and corresponds to the property resultElementName in the SearchResultGrid class of the Flex client. Basically, this is how E4X determines where each row goes in the SearchResultGrid.
  • title, length, rate, and date correspond to the entries in the fields ArrayCollection in the SearchResultGrid class, and E4X uses the text value in each node to populate the respective column in each row.

Deployment

With the Grails application and Flex search client complete, I am ready to deploy them. While there are several ways to deploy a Flex client - Grails/Java server application, Flex Ant tasks are a good option. There are three Flex Ant tasks:

  1. mxmlc – used to compile all of the ActionScript and MXML files into one SWF file that becomes the "executable" for the Flash player.
  2. html-wrapper – used to generate a simple HTML page with <object> tags to download the Flash player and run the Flex application.
  3. compc – used to compile ActionScript library files into SWF files.

Of these three tasks, you only need to work with mxmlc and html-wrapper.

To use the Flex Ant tasks:

  1. Place the flexTasks.jar file in <GRAILS_INSTALL_DIR>/ant/lib directory. The flexTasks.jar file can be found in <FLEX_SDK_DIR>/ant/lib or <FLEX_BUILDER_DIR>/sdks/3.0.0/ant/lib.
  2. Copy <SOURCES_DIR>/FlexTasks.groovy to the <GRAILS_INSTALL_DIR>/scripts directory.
  3. In the file <SOURCES_DIR>/flex-grails/flex.properties, set 'FLEX_HOME' to the location of the Flex SDK, either the standalone Flex SDK or the one included with Flex Builder. If you use the SDK included with Flex Builder, be sure to use version 3. There are several other properties in this file that have default values; the Flex documentation has detailed descriptions of the settings and the implications of each.

To complete the deployment process:

  1. Change to the <SOURCES_DIR>/flex-grails directory
  2. From the command prompt run grails flex-tasks.
  3. When the code finishes executing, the web-app directory should contain the following:

    • mainView.swf, a file run by the Flash player
    • index.gsp, a wrapper file that will load the Flash player
    • AC_OEtags.js, a file used in loading the Flash player
    • history, a directory that contains three files: history.css, history.js, and historyFrame.html
  4. From the command prompt run grails run-app.
  5. Point your browser to http://localhost:8080/movies to see the application.

Where to go from here

  1. Be sure to check out LiveCycle Data Services or the open source version BlazeDS for further remoting options.
  2. For more information on Grails development, visit http://www.grails.org or the excellent series of articles on Grails by Scott Davis.
  3. You may want to try the Grails Flex Plug-in, which makes it easy to use BlazeDS with a Flex client.
  4. There is also some great information about using Maven with Flex in Jacob von Eyben's blog.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License

About the author

Bill Bejeck is a software engineer for BAE Systems Inc. in northern Virginia. When not playing with his daughters, he spends too much time on his laptop. You can send your comments to Bill via e-mail.

  评论这张
 
阅读(526)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017