Статьи

Flex встречает Google App Engine

Adobe отлично поработала с Flex, и они намного опередили своих конкурентов в области RIA. Тем временем Google отлично справляется с несколькими проектами Java (такими как Guice, GWT) и предоставляет поддержку Java в Google App Engine. На самом деле у Google даже есть библиотека компонентов Flex с открытым исходным кодом, называемая flexLib.

Java на Google App Engine — очень важный шаг. После окончания школы я слышал, что большинство друзей выдвигали идеи, но не пытались их воплощать, в основном из-за стоимости хостинга на Java. Java — это элегантная и сложная платформа, над которой интересно работать, но она никогда не предлагает дешевых и простых альтернатив хостинга, таких как PHP. Google App Engine может наконец изменить это. Он предлагает запуск с нулевой стоимостью, гибкие варианты оплаты по мере роста вашего проекта, а также предоставляет очень простую среду разработки. Все, что вам нужно, это просто установить плагин Eclipse и начать кодирование. Даже когда создается новый проект GAE, базовый пример GWT уже включен.

Мне очень нравится сцена, где Оби-Ван Кеноби встречается с Энакином Скайуокером в Эпизоде ​​I. Куай-Гон представляет Энакина и говорит: «Энакин Скайуокер встречает Оби-Вана Кеноби». Это важная сцена, объединяющая двух разных людей на очень долгое время. Этот пост будет знакомством с Flex в Google App Engine. Два великих, но совершенно разных мира. Мы создадим очень простой сервлет для подачи данных в наше приложение Flex и используем хранилище данных Google для простого сохранения данных. Перед началом учебного курса я предполагаю, что плагин GAE и плагин Flex Builder уже установлены в вашем экземпляре Eclipse.
Вы, наверное, заметили новые три кнопки на панели инструментов. Просто нажмите «Новый проект веб-приложения».

Далее укажите пакет и название проекта.

Вы, должно быть, заметили, что мастер уже добавил GreetingService, GreetingServiceImpl и класс GWT с именем вашего проекта (в данном случае «FirstProject»). Это хорошее начало, особенно для запуска GWT, но оно нам не пригодится. Просто оставьте их там, откройте файл web.xml в разделе war / WEB-INF и добавьте описание сервлета.

Мы готовы создать сервлет для подачи нашего клиента Flex. Щелкните правой кнопкой мыши пакет org.flexjava.server и добавьте новый файл класса, расширяющий HttpServlet, как показано ниже.

Теперь пришло время разработать наш бэкэнд-сервис. Мне не очень нравятся проекты hello world, поэтому даже если мы кодируем базовый проект, можно найти реальный (но все же базовый) проект телефонной книги, который стоит кодировать. Для основной функциональности нам нужно получить список контактов, хранящихся в хранилище данных, а также нам нужно добавить новые.

Нам нужна организация для наших контактов. Давайте создадим новый класс с именем Entry и добавим аннотации, чтобы сделать наш класс Entry устойчивым.

 

package org.flexjava.server;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable
public class Entry {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
Long id;
@Persistent
private String name;
@Persistent
private String phone;

public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
// Add all getter/setters...
}

Хранилище данных GAE довольно простое в использовании. Просто создайте persistanceManager и используйте методы makePersistant или newQuery для сохранения или извлечения данных.

PersistenceManager persistenceManager = pmfInstance.getPersistenceManager();
//..
persistenceManager.makePersistent(entry);
//..
persistenceManager.newQuery(query).execute();

Давайте начнем кодировать наш сервлет, используя их.

package org.flexjava.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class FlexServiceImpl extends HttpServlet {
//persistanceManager
private static final PersistenceManagerFactory pmfInstance = JDOHelper.getPersistenceManagerFactory("transactions-optional");

@SuppressWarnings("unchecked")
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//PrintWriter to return and receive data from flex client
PrintWriter writer=resp.getWriter();
writer.println("\n");
PersistenceManager persistenceManager = pmfInstance.getPersistenceManager();
//reading parameters from http request
String operation = req.getParameter("operation");
String name = req.getParameter("name");
String phone = req.getParameter("phone");
//if adding new contact is requested
if (operation.equalsIgnoreCase("save")){
Entry entry=new Entry();
entry.setName(name);
entry.setPhone(phone);
persistenceManager.makePersistent(entry);
writer.println("Success");
//if retrieving all contact list is requested
}else if (operation.equalsIgnoreCase("get")){
//Query to retrieve all Entry data
String query = "select from " + Entry.class.getName();
List entries = (List) persistenceManager.newQuery(query).execute();
writer.println("");
for (Entry entry : entries) {
writer.println("");
writer.println(""+entry.getName()+"");
writer.println(""+entry.getPhone()+"");
writer.println("");
}
writer.println("");
}
}
}

Наш код GAE готов, теперь мы можем перейти к Flex. Чтобы включить наш проект, совместимый с Flex, щелкните правой кнопкой мыши проект и выберите Добавить Flex Project Nature.

Нажмите «Далее», чтобы продолжить.

Выберите военную папку в качестве выходной папки, чтобы файлы сборки были развернуты на сервере.

Поскольку мы только что добавили природу Flex и создали файл mxml, Flex Builder находит сбой при подготовке файлов оболочки HTML для сборки SWF. Чтобы упростить жизнь Flex Builder, перейдите на вкладку ошибок, щелкните правой кнопкой мыши ошибку и выберите пересоздать шаблон HTML. Если ошибок нет, просто пропустите это и продолжайте.

Теперь мы можем разработать собственный пользовательский интерфейс. Переключитесь в режим конструктора и перетащите 2 метки, 2 текстовых поля, кнопку и компонент сетки данных.

Now we can switch to source mode to code. We are going to use very little coding, most of the work will be done by auto XML parsing and binding the data between components and variables.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="callService('get')">
<mx:TextInput x="114" y="20" id="nameTxt"/>
<mx:TextInput x="114" y="60" id="phoneTxt"/>
<mx:Label x="29" y="22" text="Name"/>
<mx:Label x="29" y="62" text="Phone"/>
<mx:Button x="332" y="60" label="Save" click="callService('save')"/>
<!-- datagrid is directly binded to phonebook variable -->
<mx:DataGrid x="29" y="138" dataProvider="{phonebook.entry}">
<mx:columns>
<!--datafields determine which property belongs to that column-->
<mx:DataGridColumn headerText="Name" dataField="name"/>
<mx:DataGridColumn headerText="Phone" dataField="phone"/>
<mx:DataGridColumn headerText="Record Id" dataField="@id"/>
</mx:columns>
</mx:DataGrid>
<!--HTTPService can easily post and receive xml data-->
<mx:HTTPService id="httpXmlDataService" url="http://localhost:8080/firstproject/flex" resultFormat="e4x" result="resultHandler(event)" useProxy="false">
<!--xml request will be automatically formed with bindings-->
<mx:request xmlns="">
<operation>{command}</operation>
<name>
{nameTxt.text}
</name>
<phone>
{phoneTxt.text}
</phone>
</mx:request>
</mx:HTTPService>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
[Bindable]
private var command:String;
[Bindable]
private var phonebook:XML;
//xml var to hold the received data,note bindable attribute
//to enable binding

public function resultHandler(event:ResultEvent):void{
if (event.result!=null){
var xml:XML=event.result as XML;
if (xml.result=="success"){
callService("get");
}else{
phonebook=xml;
}
}
}
public function callService(command:String):void{
this.command=command;
httpXmlDataService.send();
}
]]>
</mx:Script>
</mx:Application>

So little and our client is ready, right click the project and select run as Web Application. 

GAE Plugin adds an embedded datastore and a server to your project to test. Whenever you click run the embedded services will be running and even an internal browser will run your client. Since our project name and mxml file has the same name, the default page on web.xml file point to our Flex application. Please dont forget to modify in your web.xml file if yours differ.

Easy? Well yes but still this does not release the real power and integration of Java and Flex. Next time we will focus on BlazeDs to make Flex to talk to Google App Engine. Stay tuned ?