Статьи

Flex на Grails

В этой статье, взятой из статьи « Flex on Java » (Manning, сентябрь 2010 г.), авторы Бернерд Аллмон и Джереми Андерсон показывают, как быстро создавать прототипы приложений Flex с поддержкой данных с использованием Groovy и Grails в сочетании с плагином Flex для Grails. Статья начинается с определения домена в Grails и предоставления некоторых сервисов для вашего приложения Flex, а также для самого приложения Flex. Затем он делает еще один шаг и показывает, как разрешить вашему приложению использовать JMS и ActiveMQ для обновления вашего пользовательского интерфейса в режиме реального времени. 

 

По Bernerd Allmon и Джереми Андерсон

Не все разработки в реальном мире против существующего приложения. Время от времени вам весело разрабатывать новый код. Что вы делаете, когда хотите быстро создать прототип приложения, управляемого данными, с помощью Flex? С частью Flex достаточно легко разработать пользовательский интерфейс, но как насчет бэкэнда? Вы всегда можете разработать бэкэнд на основе Java, используя те же методы и приемы, которые мы описали в этой книге, или воспользоваться другой инфраструктурой, такой как Grails

, для быстрого запуска своего бэкэнда, управляемого данными.

Получите скидку 40% на эту книгу!
Нажмите здесь, чтобы купить его непосредственно у Мэннинга и использовать код » dzone40 «. 

 

Почему Groovy и Grails?

Groovy
ласково называют Java 2.0
многими в мире Java, поэтому неудивительно, что вы можете интегрироваться с Groovy и Grails так же легко — а в некоторых аспектах — проще — как в предыдущих главах.

 
 

Вы можете спросить: «Почему Flex и Grails?» На что мы отвечаем: «Почему бы и нет?» В этой статье мы собираемся продемонстрировать, как можно быстро создавать и создавать прототипы приложений Flex с поддержкой данных, используя возможности быстрой разработки, предоставляемые Groovy и Grails в сочетании с мощным плагином Grails для Flex. Независимо от того, хотите ли вы выделить конкретную часть функциональности или создать законченное приложение, есть несколько вариантов, которые позволят вам развиваться так же быстро, как Grails.

Groovy — это Java 2.0

 

Мы собираемся предположить, что вы хотя бы немного знакомы с Groovy и Grails, но если вы никогда не видели и не делали каких-либо разработок, использующих их, вы все равно сможете следовать. Мы покажем идиоматический код Groovy, но не будем вдаваться в подробности того, что делает код, поскольку это выходит за рамки этой статьи. Если вы хотите узнать больше о Groovy, рекомендуем начать с домашней страницы Groovy или почитать книгу Groovy in Action , второе издание Dierk Koenig, опубликованную издательством Manning. В этой статье мы создадим упрощенное приложение для управления контактами, которое называется Flex Contacts . Вы создадите один экран Master-Detail,
который вы можете использовать для отслеживания ваших контактов, как показано на рисунке 11.1.

 

Рисунок 11.1 Пример приложения

Прежде чем начать писать приложение, вам нужно установить Grails.

 

Загрузка и установка Grails

Установка Grails
— довольно простая задача. Направьте ваш браузер на страницу загрузок проекта Grails и загрузите соответствующий дистрибутив для вашей платформы. Эта статья была написана с использованием Grails 1.1.2, который был последним стабильным дистрибутивом, доступным на момент написания статьи. Нет необходимости устанавливать Groovy отдельно, поскольку он включен в дистрибутив Grails. Grails доступен в двух основных формах: бинарный и исходный. Загрузите бинарный дистрибутив в формате Zip или Tar / GZ, в зависимости от вашей операционной системы.

 

После того, как вы загрузили бинарный дистрибутив для Grails, разархивируйте дистрибутив Grails в папку, например c: \ dev \ grails-1.1.2 . Затем создайте переменную среды GRAILS_HOME и укажите ее в той же папке. В качестве последнего шага добавьте GRAILS_HOME \ bin к переменной PATH, чтобы вы могли запустить исполняемый файл Grails из командной строки. Когда вы закончите, откройте командную строку и введите grails –version, и вы должны увидеть вывод, похожий на этот фрагмент.

C:\dev> grails -version

Welcome to Grails 1.1.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: C:\dev\grails-1.1.2

Base Directory: C:\dev
...

 

Поздравляем! У вас есть Grails установлен и настроен. Теперь давайте перейдем к созданию приложения Grails.

 

Создание приложения Grails

Вот где вы видите один из первых примеров соглашения



Grails о  способах конфигурации . Чтобы создать приложение Grails, необходимо открыть командную строку и перейти к папке, в которой вы хотите создать приложение Grails, например c: \ dev \ projects \, и ввести следующую команду.

C:\dev\projects\> grails create-app flex-contacts

 

С этой простой командой Grails достаточно информации, чтобы сгенерировать ваш проект для вас. Не трудно запомнить или загадочные параметры командной строки, одна простая лаконичная команда и Grails создает структуру проекта и устанавливает все необходимые зависимости. Вам даже не нужно устанавливать сервер базы данных или контейнер сервлетов для запуска приложения; все это входит в комплект поставки при создании приложения Grails. Если вы думаете, что это было легко, подождите, пока вы не увидите, как легко вы можете добавить функциональность в ваше приложение Grails с помощью плагинов

. Но сначала давайте продолжим создание приложения Grails, начав с определения модели предметной области.

 

Создать модель домена Contact

Далее вы создадите класс домена, который будет отвечать за хранение контактной информации. Для этого вам понадобится только один объект домена с именем Contact . Создайте объект Contact , введя следующую команду:

C:\dev\projects\flex-contacts\> grails create-domain-class contact

 

Это создаст класс модели домена Contact в папке grails-app / domain в вашем проекте flex-contacts. В модели домена Contact вы добавите несколько простых свойств для сохранения контактной информации, такой как имя, фамилия и адрес, а также простых ограничений проверки. Вот как будет выглядеть ваш заполненный файл Contact.groovy.

 

Contact.groovy файл

class Contact {

static contstraints = { #1
firstName(blank: false, minLength: 4, maxLength: 15)
lastName(blank: false, minLength: 4, maxLength: 25)
address(blank:false)
city(blank:false)
state(blank: false, length: 2)
zipCode(blank: false, minLength: 5, maxLength: 10)
} #1

String firstName #2
String lastName
String address
String city
String state
String zipCode #2

String toString() { #3
return firstName + " " + lastName
}
}

# 1 Ограничения
# 2 Свойства
# 3 toString ()

Класс Contact содержит поля, которые вам понадобятся для хранения таких вещей, как имя, фамилия и адрес (# 2). Вы также определили несколько ограничений (# 1), чтобы вы могли проверить, что вы получаете всю необходимую информацию из внешнего интерфейса. Вы также реализовали метод toString () (# 3), чтобы обеспечить более значимую реализацию, чем по умолчанию. Теперь давайте создадим сервис, который вы будете предоставлять приложению Flex.

 

Создать КонтактСервис

Чтобы предоставить ваше приложение Grails внешнему интерфейсу Flex, создайте службу, которая предоставит функциональность вашему приложению для выполнения операций CRUD над объектом вашего домена Contact . Для этого вы вводите следующую команду в командной строке:

C:\dev\projects\flex-contacts> grails create-service contact

 

Это создаст класс с именем ContactService , показанный в листинге 11.2, в папке grails-app / services . ContactService будет содержать методы , которые вы будете выставляя Flex потреблять в качестве удаленного обслуживания. Внутри файла ContactService.groovy вы реализуете несколько простых методов, позволяющих приложению Flex получать список всех контактов в базе данных, получать определенный контакт, сохранять контакт и удалять контакт из базы данных.

ContactService.groovy file

class ContactService {

static expose = ['flex-remoting'] #1

boolean transactional = true #2

def getContacts() { #3
return Contact.list()
}

def get(id) { #3
return Contact.get(id)
}

def update(Contact contact) { #3
contact.save()
}



def remove(Contact contact) { #3

contact.delete(flush: true)

}



}

# 1 Expose to Flex
# 2 Транзакционное свойство
# 3 Методы обслуживания

Большая часть класса ContactService должна выглядеть вам знакомой. Единственная строка, которая может выглядеть странно, это та, что содержит статический код expose = [‘flex-remoting’] (# 1). Эта единственная строка кода — все, что вам нужно для предоставления этой службы
Flex, чтобы вы могли вызывать любой из методов службы из своего приложения Flex. Вы также делаете все методы службы (# 3) в своей службе транзакционными, устанавливая свойство транзакции в true

 (# 2). Плагин Flex для Grails, который мы вскоре установим, следует философии соглашения Grails над конфигурацией в том смысле, что он абстрагирует большую часть конфигурации, которую вам нужно было бы построить, если бы это было приложение Java, использующее либо BlazeDS, либо LiveCycle Data. Услуги, чтобы выставить эту функциональность.

 

Образцы начальной загрузки

Последний шаг построения клиента Flex — это загрузка приложения с образцами данных, чтобы у вас была контактная информация в базе данных при первом запуске. Это также позволит вам увидеть, что удаленное взаимодействие Flex работает правильно. Для этого добавьте код, показанный рядом с файлом BootStrap.groovy в

  папке grails-app / conf вашего приложения.

Файл BootStrap.groovy

class BootStrap {

def init = {servletContext ->

Contact contact1 = new Contact(firstName: "Jeremy", #1
lastName: "Anderson", address: "123 Main St",
city: "Jenison", state: "MI", zipCode: "49428")
contact1.save()

Contact contact2 = new Contact(firstName: "BJ", #1
lastName: "Allmon", address: "234 Any St",
city: "Delaware", state: "OH", zipCode: "43015")
contact2.save()

}
def destroy = {
}

# 1 Пример данных

Данные начальной загрузки в Grails позволяют вводить данные в приложение каждый раз, когда вы перезапускаете его. Это можно сделать, создав пару объектов Contact (# 1) в файле BootStrap.groovy и вызвав для них функцию save (), чтобы сохранить их в базе данных. Это полезная функция Grails, когда вы продвигаетесь в процессе разработки, и вам приходится каждый раз вводить контакты вручную. Обычно вы используете этот файл для начальной загрузки любых исходных данных в вашем приложении, таких как состояния и коды состояний. Теперь вы готовы приступить к разработке интерфейса Flex для созданного вами приложения Grails.

 

Стать богатым с Flex

Теперь, когда вы создали свое приложение Grails, вы можете перейти к задаче создания клиента Flex, который будет интегрироваться с Grails. Вы начнете с установки плагина Flex
для Grails, а затем добавите приложение Flex в проект Grails.

 

 

Установка плагина Flex

В корне каталога проекта введите следующую команду, чтобы установить плагин Flex для приложения Grails:

C:\dev\projects\flex-contacts\> grails install-plugin flex

 

Эта команда отключит все библиотеки Flex, необходимые для компиляции приложения Flex. Это может занять некоторое время, потому что плагин должен устранить множество зависимостей. После прокрутки всех сообщений плагин должен быть успешно установлен. Как и многие другие функции в разработке Grails, поддержка приложения для интеграции Flex чрезвычайно проста и декларативна. Не нужно создавать файлы конфигурации, хотя некоторые файлы конфигурации содержатся в папке web-app / WEB-INF, если вам необходимо настроить параметры компилятора Flex.

 

Создание доменных классов во Flex

Вы можете начать разработку Flex, создав объект домена в ActionScript. Этот объект будет действовать как своего рода объект передачи данных, позволяя вам иметь дело с полноценными объектами, когда ваша служба возвращает данные клиенту. Этот подход избавляет от необходимости иметь дело с псевдопрокси-объектами, в которые Flex может обернуть ваши объекты, если у него не будет ничего для его преобразования.

Когда вы установили плагин Flex на предыдущем шаге, он создал папку flex в web-app / WEB-INF . Внутри этой папки находится еще одна папка с именем user-classes , которая содержит файл, который подскажет вам, куда вы должны поместить ваши классы ActionScript, соответственно называемый add_your_as_and_swc_files_here . Создайте файл в папке пользовательских классов с именем Contact.as.

Contact.as

package {

[Bindable] #1
[RemoteClass(alias = "Contact")] #2
public class Contact {

public function Contact() {
}

public var id:*; #3
public var version:*; #3

public var firstName:String #4
public var lastName:String
public var address:String
public var city:String
public var state:String
public var zipCode:String #4

}
}

# 1 Bindable
# 2 RemoteClass
# 3 Специальные свойства Hibernate
# 4 Открытые свойства

 

Код должен напоминать классы домена на стороне клиента, которые вы создали ранее для своего приложения FlexBugs. Обратите внимание на аннотации в верхней части файла, [Bindable] (# 1) и [RemoteClass]

  (# 2). [Bindable]



  аннотаций позволяет Flex знать , что всякий раз , когда один из значений изменений этого объекта, он должен уведомить что — нибудь еще , что связано с этим объектом , чтобы сообщить ему , что он должен обновляться. Мы не использовали привязку данных в нашем другом приложении, но для этого быстрого примера мы использовали его, чтобы сократить количество примеров.

Если вы забыли, аннотация [RemoteClass]



  позволяет сопоставить класс Flex с классом на стороне сервера. Класс Contact.as сопоставлен с классом домена Contact.groovy, который вы создали ранее. Поскольку в этом тривиальном примере вы используете структуру пакета, вам не нужно полностью ее здесь определять; если ваш доменный объект в Grails попал под определенный пакет, вам придется полностью квалифицировать этот объект в этой аннотации, чтобы он работал правильно.

Вам нужно добавить пару
специфичных для Hibernate
свойств (# 3) в свой класс домена
Contact, чтобы приложение работало так, как задумано, вместе со всеми обычными общедоступными свойствами (# 4), которые необходимо включить в нужные поля данных. быть способным быть настойчивым.

 

Создание приложения Flex

Теперь, когда у вас есть объект домена, созданный для клиентской стороны, вам нужно будет создать файл для самого основного приложения Flex, которое будет называться main.mxml и создается в папке веб-приложения вашего Grails. заявление.

Вы разобьете это на куски размером с кусочек, которые должно быть легче переварить, чем если бы вы просто были представлены с конечным состоянием приложения. Сначала вы начнете с создания объекта Application

  . Как и в другом примере приложения, ваше приложение Flex будет иметь элемент Application в качестве корневого узла файла MXML, как показано в этом фрагменте.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:local="*"
layout=”vertical”
creationComplete="contactService.getContacts()"
viewSourceURL="srcview/index.html">
</mx:Application>

 

Теперь, когда у вас запущено базовое приложение, вы готовы приступить к разработке основного макета.

 

Определение макета

Снова посмотрите на рисунок 11.1 и обратите внимание, что у вас есть три основных контейнера, используемых для этого приложения. В верхней части находится заголовок, содержащий текст Flex Contacts on Grails , и две панели, содержащие основной вид и подробный вид. Давайте создадим базовый макет для вашего приложения. Для этого вы собираетесь использовать несколько компонентов макета

: HBox и Panel .   Мы разобьем Main.mxml и рассмотрим каждый раздел в отдельности.

Main.mxml (a)

<mx:HBox width="100%">                                                 #1
<mx:Text fontSize="24" text="Flex Contacts on Grails"/>
</mx:HBox>
<mx:HBox width="100%" height="100%">
<mx:Panel width="65%" title="Contacts" height="100%"> #2

</mx:Panel>
<mx:Panel width="35%" title="Edit Contact" height="100%"> #3

</mx:Panel>
</mx:HBox>

Контейнер заголовка # 1
# 2 Главный вид
# 3 Подробный вид

 

В этом листинге показан код, использованный для создания макета нашего приложения. В фрагменте, который мы видели ранее, вы указали, что ваше приложение использует вертикальный в качестве основного метода компоновки, поэтому ваши компоненты будут перетекать вертикально вниз при добавлении их в приложение. Здесь вы начнете с добавления контейнера HBox (# 1), содержащего один компонент Text . Этот текстовый компонент содержит текст для нашего заголовка, который появляется в заголовке. Затем вы помещаете два контейнера Panel в другой блок HBox, чтобы они отображались в приложении рядом друг с другом. Эти два компонента Panel будут содержать главный вид (# 2) и подробный вид (# 3).

 

Создание основного вида

Внутри первого контейнера Panel вы создадите главное представление, используя компонент DataGrid , который позволяет отображать табличные данные довольно безболезненно.

Main.mxml (б)

<mx:DataGrid id="contactsGrid"
width="100%"
height="100%"
dataProvider="{contactsList}" #1
itemClick="doSelect(Contact(event.currentTarget.selectedItem))">

<mx:columns>
<mx:DataGridColumn dataField="id" headerText="ID" width="50"/> #2
<mx:DataGridColumn dataField="firstName"
headerText="First Name" width="100"/>
<mx:DataGridColumn dataField="lastName"
headerText="Last Name" width="100"/>
<mx:DataGridColumn dataField="address" headerText="Address"/>
<mx:DataGridColumn dataField="city" headerText="City" width="120"/>
<mx:DataGridColumn dataField="state" headerText="State" width="70"/>
<mx:DataGridColumn dataField="zipCode" headerText="ZipCode"
width="100"/> #2
</mx:columns>
</mx:DataGrid>

<mx:ControlBar> #3
<mx:Button label="Delete Contact"
enabled="{contactsGrid.selectedItem != null}"
click="deleteContact(selectedContact)"/>
<mx:Button label="Refresh" click="contactService.getContacts()"/>
</mx:ControlBar> #3

# 1 DataProvider
# 2 Столбцы DataGrid
# 3 ControlBar

 

В этой части списка показан код для создания DataGrid

контактов,  а также для определения отображаемых столбцов. Возможно, вы заметили элементы, содержащиеся в фигурных скобках {} ; это как указать привязку данных
в приложении Flex. Вы связали свойство dataProvider (# 1) DataGrid с переменной contactsList , которую вы определите позже. Здесь вы будете хранить результаты вызова метода RemoteObject, чтобы получить все контакты. Обратите внимание, что все имена ваших столбцов (# 2) должны соответствовать тому, что вы определили в Контакте



 

 объект, который вы создали ранее. Это позволяет Flex автоматически определять, какое поле данных сопоставить с каким столбцом.

ControlBar

(# 3) будет содержать все кнопки , необходимые для взаимодействия с этим элементом управления.

 

Создание подробного вида

Теперь, когда основной вид создан, он переходит к подробному виду. Подробное представление предоставит механизм для редактирования и обновления ваших контактов. Хотя мы могли бы разрешить редактирование прямо в самой DataGrid , это не было бы хорошим примером и не демонстрирует силу связывания данных во Flex.

Main.mxml (с)

<mx:Form id="contactForm" width="100%">                                #1
<mx:FormItem label="ID:" width="100%"> #2
<mx:Text text="{selectedContact.id}"/>
</mx:FormItem>
<mx:FormItem label="First Name:" width="100%">
<mx:TextInput id="firstName" text="{selectedContact.firstName}"/>
</mx:FormItem>
<mx:FormItem label="Last Name:" width="100%">
<mx:TextInput id="lastName" text="{selectedContact.lastName}"/>
</mx:FormItem>
<mx:FormItem label="Address:" width="100%">
<mx:TextInput id="address" text="{selectedContact.address}"/>
</mx:FormItem>
<mx:FormItem label="City:" width="100%">
<mx:TextInput id="city" text="{selectedContact.city}"/>
</mx:FormItem>
<mx:FormItem label="State:" width="100%">
<mx:TextInput id="state" text="{selectedContact.state}"/>
</mx:FormItem>
<mx:FormItem label="Zip Code:" width="100%">
<mx:TextInput id="zipCode" text="{selectedContact.zipCode}"/>
</mx:FormItem> #2
</mx:Form>

<mx:ControlBar> #3
<mx:Button label="New Contact"
enabled="true" click="selectedContact = new Contact()"/>
<mx:Button label="Save Contact"
click="updateContact(selectedContact)"/>
<mx:Button label="Reset" click="resetForm()"/>
</mx:ControlBar> #3

# 1 Form
# 2 FormItems
# 3 ControlBar

 

Здесь мы используем код для подробного представления, в котором вы используете другой объект контейнера, компонент Form

  (# 1). В отличие от своего HTML- компонента, компонент Form в Flex является строго контейнером. Вам не нужно заключать свои поля в компонент Form, чтобы публиковать данные на стороне сервера.

Внутри компонента Form вы определяете серию компонентов FormItem

  (# 2), которые содержат компоненты формы GUI, используемые для ввода данных. Это должно быть довольно очевидно. Обратите внимание на синтаксис привязки данных в текстовых атрибутах для этих компонентов. Это означает, что вы будете связывать текстовые значения этих компонентов с переменной selectedContact . В качестве последнего шага вы добавляете другую ControlBar (# 3), как вы делали для основного представления, чтобы содержать все кнопки, необходимые для управления приложением.

 

Добавление RemoteService

 

Flex имеет несколько компонентов, которые позволяют ему взаимодействовать со стороной сервера, а именно HTTPService , WebService и RemoteService . В двух словах, WebService облегчает взаимодействие с веб-сервисами на основе SOAP. HTTPService позволяет вам использовать и вызывать другие веб-сервисы, используя различные протоколы, такие как XML и JSON, и является лучшим выбором, если вы пытаетесь взаимодействовать с каким-либо ресурсом RESTful
. RemoteService использует двоичный протокол Adobe AMF
, который обеспечивает наилучшую производительность из трех.

 

Добавление RemoteService

<mx:RemoteObject id="contactService" destination="contactService">   
<mx:method name="getContacts"
result="handleGetContacts(event.result)"
fault="showFault(event)"/>
<mx:method name="update" fault="showFault(event)"/>
<mx:method name="remove" fault="showFault(event)"/>
</mx:RemoteObject>

Как указывалось ранее, вы собираетесь использовать компонент RemoteObject для облегчения связи со стороной сервера, и вы определили методы, которые вы будете вызывать, чтобы вы могли определить методы обратного вызова, которые вы будете использовать для обработки результатов возвращение с сервера, а также любые неисправности.

 

Собираем все вместе

Вы почти закончили. Теперь вы собрали все это вместе и добавили методы, которые вы будете вызывать для обработки событий из пользовательского интерфейса.

Main.mxm (d)

<local:Contact id="selectedContact"                                #1
firstName="{firstName.text}"
lastName="{lastName.text}"
address="{address.text}"
city="{city.text}"
state="{state.text}"
zipCode="{zipCode.text}"/>

<mx:ArrayCollection id="contactsList"/>

<mx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;

private function doSelect(c:Contact):void {
selectedContact = c;
}

private function handleGetContacts(list:*):void { #2
contactsList.removeAll();
for each (var c:Contact in list) {
contactsList.addItem(c);
}
}

private function showFault(fault:*):void { #3
Alert.show(fault.message);
}

private function deleteContact(selectedContact:Contact):void { #4
contactService.remove(selectedContact);
contactService.getContacts();
}

private function updateContact(contact:Contact):void {
contactService.update(selectedContact);
contactService.getContacts();
}

private function resetForm():void {
var tmpObj:Contact = Contact(contactsGrid.selectedItem);
contactService.getContacts();
contactsGrid.selectedItem = tmpObj;
doSelect(Contact(contactsGrid.selectedItem)); #4
}

]]>
</mx:Script>

# 1 Контакт
# 2 Обработчик событий RemoteObject
# 3 Обработчик ошибок RemoteObject
# 4 Обработчики событий

 

Большинство из того, что показано в списке, должно иметь смысл. Здесь вы определяете объект Contact в MXML, а не в ActionScript (# 1). Обратите внимание, что вы также выполняете привязку данных обратно к компонентам формы, создавая двустороннюю привязку между переменной selectedContact и формой сведений . Затем определите обработчик событий (# 2) и обработчик ошибок (# 3) для объекта RemoteObject, который вы определили в листинге 11.8. Наконец, у вас есть все обработчики событий для компонентов в главном представлении и подробном представлении (# 4).

Теперь, когда вы завершили эту часть приложения, вы можете запустить приложение Grails, выполнив grails run-app

  и перейдя к приложению. После запуска приложения запустите браузер и перейдите по адресу http: // localhost: 8080 / flex-contacts / main.mxml, и вы увидите нечто похожее на рисунок 11.1. У вас есть функциональное приложение Flex, работающее на Grails. В следующих нескольких разделах вы собираетесь изменить этот простой пример, чтобы использовать JMS и ActiveMQ.

 

Установите подключаемые модули Grails JMS  и ActiveMQ 




Далее вы продемонстрируете способность вашего приложения Grails передавать данные в приложение Flex с помощью компонентов Flex, которые интегрируются с JMS для создания и потребления сообщений. Это позволит вам удалить кнопку «Обновить» и некоторые сантехнические работы, необходимые для обновления Flex DataGrid, когда пользователь добавляет, редактирует или удаляет контакт. Это помогает очистить клиент за счет уменьшения количества логики представления и сложности. Чтобы установить плагин Grails JMS из корневого каталога проекта, используйте этот фрагмент:

$ grails install-plugin jms 

Затем сделайте то же самое для плагина ActiveMQ:

$ grails install-plugin activemq

 

После установки этих плагинов вы готовы к разработке. Прелесть соглашений Grails в том, что они скрывают большую часть сложности подключения новых внешних платформ, таких как JMS и ActiveMQ. Стоит отметить, что плагины JMS и ActiveMQ все еще довольно новы, но, похоже, справляются с работой в самых распространенных ситуациях. Теперь, когда у вас есть плагины для создания приложения с поддержкой JMS, вы можете перейти к обновлению кода приложения Grails. Для предоставления службы JMS клиенту Flex требуется всего несколько вещей, и они описаны ниже.

 

Добавьте бин ActiveMQ Spring


Есть одна деталь конфигурации, к которой нужно стремиться. Вам необходимо настроить плагин JMS для использования брокера ActiveMQ. Это можно сделать либо добавив bean-компонент Spring в resources.xml,
либо добавив bean-компонент с использованием подхода Groovy DSL. В следующем фрагменте демонстрируется добавление bean-компонента с использованием подхода DSL, заключающегося в добавлении фабрики соединений в качестве bean-компонента в файл конфигурации resources.groovy, расположенный в папке приложения grails-app / conf / spring .

 

// Place your Spring DSL code here
beans = {
connectionFactory(org.apache.activemq.ActiveMQConnectionFactory) {
brokerURL = "vm://localhost"
}
}

 

Приведенный здесь код представляет собой способ Groovy для конфигурирования bean-компонентов Spring в Grails, он определяет bean-компонент connectionFactory типа ActiveMQConnectionFactory и инициализирует его свойство brokerURL, указывая на vm: // localhost . Теперь, когда вы получили конфигурацию, вы можете перейти к настройке класса домена Contact .

class Contact implements Serializable {
...
}

 

Для хранения сообщений в очереди сообщений объекты должны реализовывать интерфейс Serializable

  . Вам необходимо обновить класс Contact, чтобы реализовать интерфейс Serializable, как показано ранее.

 

Подпишите клиента Flex на сервис Grails JMS

Теперь вы готовы настроить инфраструктуру Flex в качестве потребителя JMS

. Сначала вы начнете с настройки BlazeDS.

Обновите services-config.xml

Вам нужно настроить Flex с contactsTopic в файле конфигурации BlazeDS верхнего уровня. Когда подключаемый модуль Flex установлен, он помещает файл services-config.xml
в каталог / web-app / WEB-INF / flex . Давайте отредактируем его, добавив службу сообщений Flex внутри элемента services. Полный файл services-config.xml включен в следующий список для ясности и того, что порядок определений бинов имеет значение. Внутри элемента сервисов сначала идет сервис Grails, а затем конфигурация JMS
.

 

услуги-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<services-config>
<services>
<service id="grails-remoting-service"
class="flex.messaging.services.RemotingService">
<adapters>
<adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter"
default="true"/>
</adapters>
</service> <service id="grails-service"
class="org.codehaus.groovy.grails.plugins.flex.GrailsBootstrapService"/>
<service id="message-service" #1
class="flex.messaging.services.MessageService" #1
messageTypes="flex.messaging.messages.AsyncMessage"> #1
<adapters> #2
<adapter-definition id="jms" #2
class="flex.messaging.services.messaging.adapters.JMSAdapter" #2
default="true"/> #2
</adapters> #2
<destination id="contactsTopic"> #3
<properties> #3
<jms> #3
<destination-jndi-name>contacts</destination-jndi-name> #3
<message-type>javax.jms.ObjectMessage</message-type> #3
<connection-factory>ConnectionFactory</connection-factory> #3
<delivery-mode>NON_PERSISTENT</delivery-mode> #3
<message-priority>DEFAULT_PRIORITY</message-priority> #3
<acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode> #3
<transacted-sessions>false</transacted-sessions> #3
<initial-context-environment> #3
<property> #3
<name>Context.PROVIDER_URL</name> #3
<value>vm://localhost</value> #3
</property> #3
<property> #3
<name>Context.INITIAL_CONTEXT_FACTORY</name> #3
<value>org.apache.activemq.jndi.ActiveMQInitialContextFactory</value> #3
</property> #3
<property> #3
<name>topic.contacts</name> #3
<value>contacts</value> #3
</property> #3
</initial-context-environment> #3
</jms> #3
</properties> #3
</destination> #3
</service>
<default-channels>
<channel ref="grails-amf"/>
</default-channels>
</services>
<channels>
<channel-definition id="grails-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>

# 1 JMS-сервис
# 2 JMS-адаптер
# 3 JMS-конфигурация

 

Основная часть файла services-config.xml была сгенерирована при установке подключаемого модуля Flex; однако вам необходимо добавить новый раздел службы для службы JMS, который вы будете использовать (# 1), и раздел, в котором указано, что вы хотите, чтобы служба использовала адаптер JMS (# 2). Вам также необходимо настроить тему JMS, с которой вы будете общаться (# 3). Чтобы увидеть все параметры, которые вы определили, обратитесь к пользовательской документации BlazeDS . Теперь давайте перейдем к изменению нашего ContactService для использования вашего обмена сообщениями.

 

Изменение ContactService


Существующий класс ContactService относительно прост. Вот обновленный класс ContactService с дополнениями для публикации обновленного списка контактов.

КонтактСервис обновлен


class ContactService {

static expose = ['flex-remoting']
boolean transactional = true

def getContacts() {
return Contact.list()
}

def get(id) {
return Contact.get(id)
}

def update(Contact contact) {
contact.save()
publishContacts() #1
}

def remove(Contact contact) {
contact.delete(flush: true)
publishContacts() #1
}

def private void publishContacts() {
try {
sendPubSubJMSMessage("contacts", getContacts()); #2
} catch (Exception e) {
log.error("Failed to publish contacts.", e);
}
}
}

# 1 publishContacts
# 2 sendPubSubJMSMessage

 

Вы добавляете метод publishContacts () (# 1) для публикации обновлений в теме, настроенной вами в файле services-config.xml . SendPubSubJMSMessage

 (# 2) принимает два аргумента. Первый аргумент — это имя назначения JNDI, определенное в вашей теме, а второй — список контактов. Затем вы подключаете обновление и удаляете методы для публикации контактов, когда они вызываются. Другие методы могут быть вызваны в зависимости от ваших потребностей. Поскольку тема поддерживает модель публикации / подписки, она используется для обмена сообщениями «один ко многим», что хорошо работает с приложением «Контакты». Для обмена сообщениями «один-к-одному» или «точка-точка» вместо этого следует использовать очередь. Чтобы узнать больше о плагине JMS,посетите веб-сайт Grails .

 

Обновите Main.mxml

Последнее, что нужно сделать перед повторным запуском приложения контактов, это обновить файл main.mxml клиента Flex. Вы добавите JMS-сервис к миксу и внесете другие незначительные изменения. Начнем с элемента Application .

Main.mxml (e)

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:local="*"
layout="vertical"
viewSourceURL="srcview/index.html"
#1
creationComplete="contactService.getContacts();jmsConsumer.subscribe()">

<mx:Consumer id="jmsConsumer" #2
destination="contactsTopic"
message="handleGetContacts(event.message.body)"
fault="showFault(event)"/>

...

</mx:Application>

# 1 creationComplete
# 2 Consumer

 

Объект Flex Consumer (# 2) используется для подключения к contactsTopic . Когда приложение инициализируется, вам необходимо подписаться на contactsTopic . Для этого вы настраиваете определение события creationComplete (# 1) для вызова подписки на jmsConsumer

. Потребитель прослушивает изменения от брокера ActiveMQ и использует метод handleGetContacts для получения данных. Этот метод обновляет список контактов при наличии обновлений.

Отсюда приложение будет работать нормально, как есть. Есть некоторые вещи, которые нужно очистить, потому что теперь мы делаем приложение осведомленным о JMS, и они не требуют дополнительных затрат.

Main.mxml (f)

private function deleteContact(selectedContact:Contact):void {
contactService.remove(selectedContact);
}

private function updateContact(contact:Contact):void {
contactService.update(selectedContact);
}
...
<mx:ControlBar>
<mx:Button label="Delete Contact"
enabled="{contactsGrid.selectedItem != null}"
click="deleteContact(selectedContact)"/>
</mx:ControlBar>

 

Вы удаляете вызовы метода getContacts () в RemoteObject при вызове deleteContact и updateContact . Эти вызовы были необходимы до включения JMS для обновления DataGrid при каждом обновлении списка контактов. Вы также можете удалить кнопку Обновить. Потребитель Flex будет получать обновления каждые несколько секунд и будет вызывать метод, который будет обновлять DataGrid, чтобы больше не было необходимости в этих дополнительных вызовах на стороне сервера. Сам потребитель может быть дополнительно настроен, если требуются другие временные или другие параметры.

Чтобы проиллюстрировать передачу информации с сервера на клиент, запустите приложение Grails, открыв командную строку и перейдя в папку проекта. Введите команду grails run-app, которая запустит встроенный контейнер для запуска приложения. Теперь откройте два браузера и укажите их оба на приложение Flex по адресу http: // localhost: 8080 / flex-contacts / main.mxml . Затем, когда вы делаете обновления в одном окне, вы должны видеть, что контакты обновляются в другом окне браузера — больше не нужно вручную обновлять приложение, чтобы получить изменения других пользователей.

 

Резюме

В этой статье мы показали, как быстро создавать прототипы приложений Flex с поддержкой данных, используя Groovy и Grails в сочетании с плагином Flex для Grails. Вы начали с определения домена в Grails и предоставления некоторых сервисов для своего приложения Flex и самого приложения Flex. Затем вы пошли еще дальше и позволили вашему приложению использовать JMS и ActiveMQ для обновления вашего пользовательского интерфейса в режиме реального времени.