Перейти к тексту

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Вся введенная информация защищена.

  • Закрыть [x]

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

Вся введенная информация защищена.

  • Закрыть [x]

Создание Web-приложений на базе Flex 4 и Java

Учимся применять удаленное взаимодействие объектов

Аррон Фергюсон, преподаватель, технологический институт Британской Колумбии
Аррон Фергюсон (Arron Ferguson) в течение 12 лет преподавал программирование в технологическом институте Британской Колумбии. Его профессиональные интересы и опыт охватывают такие области, как Java, XML, Web-технологии, анимация (2D и 3D), и создание объектов цифровой мультимедиа. Он также имеет опыт работы независимым техническим редактором и рецензентом, а также является автором книги "Создание систем управления контентом в Java" (Charles River Media, 2006 г.). Наконец, Аррон является горячим сторонником Linux и программного обеспечения с открытым кодом.

Описание:  Для разработки насыщенных Интернет-приложений (Rich Internet Application, RIA) можно использовать различные технологии. Правильный выбор комплекса технологий позволяет сократить время разработки приложений и предоставить пользователям функционально богатые Интернет-приложения. Из этой статьи вы узнаете, как использовать компоненты платформы Java™ EE на стороне сервера, компоненты платформы Adobe® Flex™ на стороне клиента, а также СУБД MySQL® в качестве хранилища данных.

Дата:  21.09.2011
Уровень сложности:  средний PDF:  A4 and Letter (104 КБ | 21 страница)Загрузить Adobe® Reader®
Активность:  4881 просмотров
Комментарии:  


К современным Web-приложениям предъявляются все более высокие требования. Они должны уметь работать с учетными данными пользователей, обеспечивать загрузку контента и потокового видео. Эти задачи требуют использования технологий, ускоряющих процесс разработки и в то же время обеспечивающих поддержку всех наиболее востребованных функций. Разработчики приложений RIA должны уметь правильно выбирать комплексы технологий, позволяющие наилучшим образом решать поставленные задачи.

Часто используемые сокращения

  • AMF: Action Message Format – формат сообщений о действиях
  • API: Application programming interface – интерфейс программирования приложения
  • CSS: Cascading stylesheet – каскадная таблица стилей
  • GUI: Graphical user interface – графический интерфейс пользователя
  • HTTP: Hypertext Transfer Protocol – протокол передачи гипертекста
  • JAR: Java archive – архив Java
  • POJO: Plain old Java object – простой Java-объект в старом стиле
  • RIA: Rich Internet Application – насыщенное Интернет-приложение
  • RPC: Remote procedure call – удаленный вызов процедуры
  • SDK: Software development kit – набор инструментальных средств разработки программного обеспечения
  • SQL: Structured Query Language – язык структурированных запросов
  • UI: User interface – пользовательский интерфейс
  • WAR: Web archive – Web-архив
  • XML: Extensible Markup Language – расширяемый язык разметки

Adobe Flex – это технология, работающая на стороне клиента и позволяющая разработчикам использовать богатый набор API-вызовов для создания графических пользовательских интерфейсов, вывода графики, воспроизведения мультимедиа-содержимого и подключения к Web-сервисам. Технология Java, применяемая на стороне сервера, обеспечивает такие возможности, как подключение к реляционным СУБД, многопоточная обработка запросов на обслуживание и оптимальное масштабирование в случаях увеличения нагрузки. Совместное использование этих двух технологий дает мощную техническую основу для создания RIA-приложений.

В этой статье будет показано, как написать простое, но мощное RIA-приложение, использующее технологию Flex на стороне клиента, технологию Java на стороне сервера и СУБД MySQL в качестве системы хранения данных.

Пример приложения

В нашем примере приложения (см. раздел Загрузка) имеется функционально насыщенный пользовательский интерфейс, поддерживающий создание, чтение, обновление и удаление (функции CRUD – Create, Read, Update, Delete) информации о контакте через приложение Adobe Flash® (SWF). На рисунке 1 изображена трехуровневая Web-архитектура, в которой клиентская часть представлена SWF-файлом, встроенным в Web-страницу, серверная часть выполняется внутри контейнера Java-сервлета (в нашем случае это Apache Tomcat), а в качестве базы данных используется MySQL. Совместное использование этих трех технологий позволяет создать мощное распределенное приложение.


Рисунок 1. Приложение Contacts
Рисунок 1. Приложение Contacts

Для обеспечения взаимодействия между Flash-приложением и контейнером Java-сервлета инфраструктура BlazeDS предоставляет в ваше распоряжение функцию удаленного взаимодействия с объектами – особую форму удаленного вызова процедур, позволяющую объектам Adobe ActionScript™ обращаться к объектам Java и наоборот. Взаимодействием между приложением Java-сервера и реляционной базой данных управляет ORM-инфраструктура Hibernate, которая позволяет преобразовывать объекты Java в код SQL и наоборот.


Серверная часть приложения

Сначала мы создадим Java-класс, содержащий всю информацию, необходимую для хранения данных о контактах. В нашем тестовом приложении реализована простая модель, содержащая базовую информацию. В объектах Contact используются следующие атрибуты и типы данных.

- String emailAddress
- String firstName
- long id
- String lastName
- String phoneNumber
- long serialVersionUID
+ Contact()
+ Contact(String first, String last, String email, String number)
+ String getEmailAddress()
+ String getFirstName()
+ long getId()
+ String getLastName()
+ String getPhoneNumber()
+ void setEmailAddress(String address)
+ void setFirstName(String first)
+ void setId(long newId)
+ void setLastName(String last)
+ void setPhoneNumber(String number)
+ StringtoString()

Аннотации бизнес-объекта

Java-класс Contact считается классом POJO, выступающим в роли бизнес-объекта; это означает, что в нем должны быть реализованы функции и методы конкретной бизнес-области. Данные внутри объектов класса Contact необходимо сохранять в базе данных. Решением этой задачи является использование инфраструктуры объектно-реляционного отображения (ORM), такой как Hibernate, которая выполняет всю основную работу по преобразованию объектов в записи таблиц БД и обратно. Если вы используете аннотации Java Persistence API (JPA), для реализации ORM требуется написать лишь незначительное количество кода. В листинге 1 представлена аннотация Java-класса Contact.


Листинг 1. Java-класс Contact
	
package bcit.contacts;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

@Entity
@Table(name="contact")
@NamedQueries( {
    @NamedQuery(name = "contact.findAll", query = "from Contact"),
    @NamedQuery(name = "contact.getById", query =
        "select c from Contact c where c.id = :id")
} )
public class Contact {

    private static final long serialVersionUID = 123456789L;

    public Contact() {
        firstName = "N/A";
        lastName = "N/A";
        emailAddress = "N/A";
        phoneNumber = "N/A";
    }

    public Contact(String first, String last, String email, String number) {
        firstName = first;
        lastName = last;
        emailAddress = email;
        phoneNumber = number;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false, updatable=false)
    private long id;

    @Column(name = "lastName", nullable = false, unique = false)
    private String lastName;

    @Column(name = "firstName", nullable = false, unique = false)
    private String firstName;

    @Column(name = "emailAddress", nullable = false, unique = false)
    private String emailAddress;

    @Column(name = "phoneNumber", nullable = false, unique = false)
    private String phoneNumber;

    public void setPhoneNumber(String number) { phoneNumber = number; }

    public String getPhoneNumber() { return phoneNumber; }

    public String getEmailAddress() { return emailAddress; }

    public void setEmailAddress(String address) { emailAddress = address; }

    public String getFirstName() { return firstName; }

    public void setFirstName(String first) { firstName = first; }

    public String getLastName() { return lastName; }

    public void setLastName(String last) { lastName = last; }

    public long getId() { return id; }

    public void setId(long newId) { id = newId; }

    @Override
    public String toString() {
        return id + " " + firstName + " " + lastName + " " + emailAddress
            + " " + phoneNumber;
    }
}

Начнем рассмотрение этого простого класса с используемых в нем аннотаций.

  • @Column: маркирует свойство в качестве столбца базы данных, позволяя задавать для него имя, определять уникальность и возможность хранить null-значения.
  • @Entity: объявляет класс в качестве объекта entity bean; это означает, что данный класс является классом POJO, предназначенным для сохранения.
  • @GeneratedValue: определяет метод генерации первичных ключей; доступны значения AUTO, IDENTITY, SEQUENCE и TABLE
  • @Id: определяет свойство в качестве уникального идентификатора (то есть первичного ключа) для каждого Java-объекта.
  • @NamedQueries: хранит список именованных запросов.
  • @NamedQuery: объявляет предопределенный запрос в качестве строковой константы; обратившись к ней впоследствии, можно вызвать запрос на исполнение.
  • @Table: объявляет Java-класс в качестве таблицы базы данных.

Каждый раз, когда необходимо сохранить находящийся в памяти Java-объект, Hibernate преобразует информацию о его состоянии в SQL-оператор UPDATE. Аналогичным образом SQL-операторы с их возвращаемыми наборами данных используются для формирования Java-объектов. В результате этих операций все объекты могут сохраняться в базе данных в виде записей, а все записи могут быть извлечены из базы данных и преобразованы обратно в Java-объекты.

Аннотации указывают Hibernate, какие компоненты класса должны считаться сохраняемыми. Но это только часть картины.

Бизнес-сервис: связь с базой данных

Для обращений к библиотеке Hibernate с целью выполнения ORM-преобразований нам потребуется служебный класс. В листинге 2 представлен код класса ContactsService, выступающего в роли сервиса приложений.


Листинг 2. Класс ContactsService
	
public class ContactsService {

    private static Logger logger = Logger.getLogger(ContactsService.class);

    private static final String PERSISTENCE_UNIT = "contacts";

    private static EntityManagerFactory emf = null;

    static {
        logger.info("LOADING CONTACTSSERVICE CLASS.");
        emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
    }

    public ContactsService() {
        super();
    }

    public void addContact(Contact c) {
        if(c == null) {
            return;
        }

        EntityManager em = emf.createEntityManager();
        logger.info("PERSISTENCE ENTITYMANAGER ACQUIRED.");

        logger.info("ABOUT TO ADD CONTACT: fName: " + c.getFirstName()
            + ", lName: " + c.getLastName() + ", email:" + c.getEmailAddress()
            + ", phone: " + c.getPhoneNumber());
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            em.merge(c);
            tx.commit();
        } catch (Exception e) {
            logger.error("CONTACT APP PERSISTING ERROR: " + e.getMessage());
            tx.rollback();
        } finally {
            logger.info("CONTACT APP CLOSING ENTITY MANAGER.");
            em.close();
        }
    }

    public void editContact(Contact c) {
        logger.info("CONTACT TO UPDATE: " + c);
        addContact(c);
    }

    public void deleteContact(Long id) {
        logger.info("ABOUT TO DELETE CONTACT");

        EntityManager em = emf.createEntityManager();
        logger.info("PERSISTENCE ENTITYMANAGER ACQUIRED.");

        Query contactByIdQuery = em.createNamedQuery("contact.getById");
        contactByIdQuery.setParameter("id", id);
        Contact c = (Contact) contactByIdQuery.getSingleResult();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            em.remove(c);
            tx.commit();

        } catch (Exception e) {
            logger.error("CONTACT APP PERSISTING ERROR: " + e.getMessage());
            tx.rollback();
        } finally {
            logger.info("CONTACT APP CLOSING ENTITY MANAGER.");
            em.close();
        }
    }

    public List<Contact> getContacts() {
        logger.info("ABOUT TO RETRIEVE CONTACTS");

        EntityManager em = emf.createEntityManager();
        logger.info("PERSISTENCE ENTITYMANAGER ACQUIRED.");

        Query findAllContactsQuery =
            em.createNamedQuery("contact.findAll");
        List<Contact> contacts = findAllContactsQuery.getResultList();

        if (contacts != null) {
            logger.debug("CONTACT APP RETRIEVED: " + contacts.size()
                + " CONTACT(S)");
        }
        return contacts;
    }
}

Каждый метод получает ссылку на класс EntityManager, который представляет собой хранящийся в памяти кэш. Кэширование - мощная технология, обеспечивающая эффективность работы, поскольку запись и получение информации из базы данных могут отнимать много ресурсов. С вашей стороны требуется лишь обеспечить фиксацию или откат (в случае необходимости) каждой транзакции для кэшированных данных.

В JPA кэш представлен классом EntityManager, и для его для обозначения используется термин контекст хранения. Каждый контекст хранения управляет набором сущностей, которые являются Java-объектами, объявленными при помощи аннотаций @Entity. Класс EntityManagerFactory представляет собой модуль хранения, отвечающий за настройку подключений к хранилищу данных (например, к реляционной БД), управление типами сущностей (то есть всеми классами указанного контекста, которые необходимо преобразовывать для размещения в хранилище данных) и, наконец, за предоставление доступа к экземплярам контекста хранения (то есть класса EntityManager).

Испытайте бесплатную версию сервера баз данных DB2 Express 9

Бесплатный, простой в использовании и развертывании сервер DB2 Express-C настраивается за считанные минуты, содержит функции самоуправления и всю базовую функциональность СУБД DB2 для платформ Linux®, UNIX® и Windows®, включая поддержку pureXML™. DB2 Express-C предоставляет те же основные возможности, что и другие редакции DB2 Express, и является отличной основой для создания и развертывания приложений, написанных на C/C++, Java, .NET®, PHP, Ruby on Rails, Python и других языках программирования.

В отличие от создания контекста хранения, создание модуля хранения может занять много времени. Настройка подключения к хранилищу данных, нахождение всех классов, объявленных как сущности, и настройка логики для привязки этих классов к сущностям хранилища данных требуют больших затрат. Поэтому создавать экземпляр класса EntityManagerFactory следует во время запуска приложения. Что касается контекста хранения – необходимо позаботиться о том, чтобы перед созданием каждого экземпляра EntityManager всегда уничтожался предыдущий экземпляр. Другое важное правило заключается в необходимости следовать модели entitymanager-per-request, которая группирует обращения к базе данных (например, запросы и операции обновления) таким образом, чтобы все они передавались одновременно. Такая модель позволяет использовать все преимущества механизма кэширования JPA.

Теперь перейдем к написанию клиентской части приложения.


Клиентская часть приложения

Инфраструктура Flex позволяет создавать приложения, которые пользователи могут воспроизводить с помощью Adobe Flash Player. Flex состоит из следующих компонентов.

  • Основанный на XML декларативный язык описания интерфейсов, известный как MXML
  • Язык программирования ActionScript.
  • Библиотеки времени выполнения для создания пользовательских интерфейсов, Web-соединений, а также для реализации многих других возможностей.
  • Инструменты для компиляции приложений в SWF-файлы.

В клиентском приложении, рассматриваемом в этой статье, используется инфраструктура Flex версии 4. Прежде чем перейти к клиентскому приложению, важно понять, как создаются приложения Flex и как они существуют в форме исполняемых файлов внутри Flash Player.

Сначала вы можете создать приложение, используя комбинацию разметки MXML и кода ActionScript. Общая последовательность действий заключается в написании GUI-интерфейса (уровень представления) с использованием формата MXML и последующем написании кода ActionScript (бизнес-логика и обработка событий). Поскольку работа с MXML и ActionScript происходит в текстовом режиме, для создания Flash-приложений требуется только текстовый редактор и инструментарий Flex SDK.

После написания приложения Flex его код компилируется с помощью компилятора MXML. Компилятор MXML создает SWF-файлы, которые могут быть запущены в Web-браузере (с помощью плагина Flash Player).

Наконец, Flash-приложения выполняются внутри виртуальной машины ActionScript Virtual Machine 2 (AVM2) по принципу "временной линейки" (timeline). В соответствии с этим принципом выполнение программы разбивается на кадры, подобно кинофильму. На этапе компиляции Flash-приложения вы задаете для него требуемое количество кадров в секунду. Кроме того, выполнение приложений Flash Player разбивается на ряд следующих задач.

  • События Flash Player, такие как таймер и события мыши.
  • Пользовательский код.
  • Логика предварительного рендеринга, на этапе которого Flash Player пытается определить необходимость обновления графического интерфейса пользователя вследствие изменения исходных значений.
  • Пользовательский код, связанный с изменением исходных значений.
  • Рендеринг Flash Player.

Если требуется выполнять рендеринг лишь нескольких кадров в секунду, можно выполнять больше пользовательского кода. Однако если требуемая частота кадров высока (например, 60 кадров в секунду), Flash Player может не справиться с обработкой большого объема пользовательского кода, поскольку для его выполнения может не хватить отведенного времени. Об этом важно помнить при написании приложений для Flash Player.

MXML

MXML – это мощный декларативный XML-формат, реализующий следующие возможности.

  • Минимизация объема кода (в силу декларативной сущности формата XML), требуемого для написания графического интерфейса.
  • Упрощение кода графического интерфейса благодаря четкому разделению логики представления и логики взаимодействия.
  • Поддержка подхода к разработке ПО с использованием шаблонов проекта.

В листинге 3 представлен код MXML-класса Application.


Листинг 3. Класс ContactsApp
	
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
  xmlns:contact="bcit.contacts.*" creationComplete="initPage();"
  layout="vertical" frameRate="30" pageTitle="Contacts Example"
  horizontalAlign="center" verticalAlign="middle" 
  backgroundColor="#A9C0E7">


  <mx:Style>
    .mainBoxStyle {
      borderStyle: solid;
      paddingTop: 5px;
      paddingBottom: 5px;
      paddingLeft: 5px;
      paddingRight: 5px;
    }

    .textMessages {
      fontWeight: bold;
    }
  </mx:Style>


  <mx:RemoteObject id="remotingService" showBusyCursor="false"
    destination="contacts" fault="handleFault(event);"
    result="handleResult(event);"/>

  <mx:Script>
    <![CDATA[

        import mx.rpc.events.FaultEvent;
        import mx.rpc.events.ResultEvent;
        import mx.collections.ArrayCollection;
        import bcit.contacts.dto.Contact;

        [Bindable]
        private var contacts:ArrayCollection = new ArrayCollection();

        // For more on the Bindable metadata tag, see the devguide_flex3.pdf
        // document, page 1249 (1257 in PDF page numbering)
        [Bindable]
        private var message:String = "Status: Ready";

        private var contact:Contact;

        public function setControlBarValid(valid:Boolean):void {
            if(valid) {
                // if the selected item is -1, then no item is selected but at
                // the same time the fields are valid which means the user chose
                // to add a contact, not update one
                if(contactsDataGrid.selectedIndex == -1) {
                    createButton.enabled = valid;
                } else {
                    editButton.enabled = valid;
                }
              } else {
                  // else nothing is valid
                  createButton.enabled = false;
                  editButton.enabled = false;
            }
        }

        private function initPage():void {
            editContactForm.setApp(this);
            contact = new Contact();
            getAllContacts();
            resetPage();
        }

        private function createContact():void {
            contact = editContactForm.getContact();
            remotingService.addContact(contact);
            message = "Status: Contact Added";
            getAllContacts();
        }

        private function editContact():void {
            var id:Number = contact.id;
            contact = editContactForm.getContact();
            contact.id = id;
            remotingService.editContact(contact);
            message = "Status: Contact Edited";
            getAllContacts();
        }

        private function deleteContact():void {
            if(contactsDataGrid.selectedItem != null) {
                var c:Contact = contactsDataGrid.selectedItem as Contact;
                // no sense in sending the whole contact - just send the id
                // to cut down on bandwidth
                remotingService.deleteContact(c.id);
                message = "Status: Contact Deleted";
            }
            getAllContacts();
        }

        private function getAllContacts():void {
            loadButton.enabled = false;
            remotingService.getContacts();
            loadButton.enabled = true;
            resetPage();
        }

        private function populateFormWithContact():void {
            contact = contactsDataGrid.selectedItem as Contact;
            editContactForm.setContact(contact);
            editButton.enabled = true;
            deleteButton.enabled = true;
        }

        private function resetPage():void {
            editContactForm.clearForm();
            contact = new Contact();
            createButton.enabled = false;
            editButton.enabled = false;
            deleteButton.enabled = false;
            contactsDataGrid.selectedIndex = -1;
        }

        private function handleFault(e:FaultEvent):void {
            message = "Status: Error"
                + "\nFault code: " + e.fault.faultCode
                + "\nFault detail: " + e.fault.faultDetail
                + "\nFault string: " + e.fault.faultString;
        }

        private function handleResult(e:ResultEvent):void {
            // can get the results by accessing e.result property
            //mx.controls.Alert.show(e.toString());
            contacts = e.result as ArrayCollection;
            var number:int = contacts.length;
            //if(number == 1) {
            //    message = "Status: Retrieved 1 contact";
            //} else {
            //    message = "Status: Retrieved " + contacts.length + " contacts";
            //}
        }

    ]]>
  </mx:Script>

  <mx:VBox styleName="mainBoxStyle">

    <mx:Text id="titleText" text="Single click to select a contact"/>

    <contact:ContactsDataGrid id="contactsDataGrid" dataProvider="{contacts}"
      itemClick="populateFormWithContact();"
      doubleClick="populateFormWithContact();"/>

    <contact:EditContactForm id="editContactForm"/>

    <mx:ControlBar horizontalAlign="center">
      <mx:Button label="List" id="loadButton" click="getAllContacts()"
        toolTip="Retrieve contacts from the server"/>
      <mx:Button label="Add" id="createButton" click="createContact()"
        toolTip="Create a new contact"/>
      <mx:Button label="Update" id="editButton" click="editContact()"
        toolTip="Edit a selected contact"/>
      <mx:Button label="Delete" id="deleteButton" click="deleteContact()"
        toolTip="Delete a selected contact"/>
      <mx:Button label="Clear Form" id="clearButton" click="resetPage()"
        toolTip="Clear the form"/>
    </mx:ControlBar>

    <mx:TextArea text="{message}" styleName="textMessages" wordWrap="true"
      verticalScrollPolicy="auto" horizontalScrollPolicy="off" editable="false"
      width="100%"/>

  </mx:VBox>

</mx:Application>

Остановимся на рассмотрении наиболее важных моментов листинга 3 .

  • Корневым элементом MXML-документа является подкласс класса Application.
  • Элемент mx:Style позволяет задать свойства CSS для локального оформления компонентов пользовательского интерфейса. Оформление можно задать с помощью локальных определений (как это сделано в листинге 3), ссылок на внешние таблицы стилей, указания стилей внутри компонентов, а также с помощью метода setStyle языка ActionScript.
  • Класс RemoteObject представляет собой объект HTTP-сервиса, выполняющий операции удаленного взаимодействия с сервером.
  • Элемент mx:Script содержит блоки кода ActionScript, заключенные в раздел CDATA.
  • В коде присутствует только одна компоновка (то есть класс VBox).
  • Каждый раз, когда в приложении объявляется компонент пользовательского интерфейса (например, TextArea), генерируется переменная экземпляра, на которую впоследствии можно ссылаться с помощью атрибута компонента id.
  • Привязка данных осуществляется с помощью фигурных скобок (например, атрибут text элемента TextArea привязан к переменной экземпляра языка ActionScript message).

ActionScript

Пользовательский интерфейс определяется с помощью MXML, а язык ActionScript используется для обработки событий, привязки данных (через тег метаданных [Bindable]) и обращения к удаленным сервисам. Все методы в листинге 3createContact, editContact, deleteContact и getAllContacts – обращаются к удаленным методам на стороне сервера. При вызове удаленных методов ActionScript можно использовать для обработки результатов (как успешных, так и неудачных) путем объявления функций обратного вызова. Функция handleResult в листинге 3 получает результат в качестве объекта Object и передает его объекту ArrayCollection. BlazeDS преобразует объект List в объект ArrayCollection на стороне сервера.

В листинге 4 представлен ActionScript-код класса Contact, который создается для представления объектов контакта на стороне Flash.


Листинг 4. ActionScript-класс Contact
	
package bcit.contacts.dto {

[RemoteClass(alias="bcit.contacts.Contact")]
public class Contact {

    public function Contact() { id = -1; }

    public var id:Number;
    public var lastName:String;
    public var firstName:String;
    public var emailAddress:String;
    public var phoneNumber:String;

    public function toString():String {
        return id + ", " + firstName + " " + lastName + " " + emailAddress
            + " " + phoneNumber;
    }
}
}

Эти объекты ActionScript передаются на сторону сервера, где BlazeDS преобразует объекты ActionScript в объекты Java. ActionScript-класс Contact рассматривается как объект передачи данных (Data Transfer Object, DTO).


Настройка приложения

Приложение, рассматриваемое в этой статье, использует конфигурационные файлы, содержащие параметры сервера. Две важнейшие области конфигурирования – это Hibernate и BlazeDS.

Настройка Hibernate

Параметры инфраструктуры Hibernate можно настроить с помощью стандартного конфигурационного файла JPA persistence.xml, представленного в листинге 5.


Листинг 5. Конфигурационный файл persistence.xml
	
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
  http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="contacts" transaction-type="RESOURCE_LOCAL">
    <properties>
      <property name="hibernate.dialect"
        value="org.hibernate.dialect.MySQLDialect" />
      <property name="hibernate.default_schema" value="contacts" />
      <property name="hibernate.connection.driver_class"
        value="com.mysql.jdbc.Driver" />
      <property name="hibernate.connection.url"
        value="jdbc:mysql://localhost:3306/contacts" />
      <property name="hibernate.archive.autodetection" value="class, hbm"/>
      <property name="hibernate.connection.username" value="root"/>
      <property name="hibernate.connection.password" value="root"/>
    </properties>
  </persistence-unit>
</persistence>

Чтобы обеспечить доступ к данным файла persistence.xml в среде Hibernate, его необходимо поместить в папку Web-приложения WEB-INF/classes/META-INF. После того как файл будет помещен в указанную папку, он должен содержать следующую информацию.

  • Диалект базы данных (к какой именно базе данных происходят обращения, поскольку разные базы данных могут иметь разные SQL-диалекты).
  • Табличное пространство, определенное с помощью схемы по умолчанию.
  • Драйвер, использующийся для подключения к базе данных
  • URL-адрес базы данных.
  • Объекты для автоматического обнаружения (например, аннотированные классы, XML-файлы сопоставлений Hibernate и так далее).
  • Имя и пароль пользователя.

Остальные параметры могут влиять на работу Hibernate, но не являются обязательными.

Настройка BlazeDS

Инфраструктура BlazeDS настраивается с помощью четырех конфигурационных файлов.

  • messaging-config.xml: файл настройки схемы обмена сообщениями "издатель-подписчик".
  • proxy-config.xml: файл настройки параметров прокси для HTTP- и Web-сервисов.
  • remoting-config.xml: файл настройки параметров сервисов удаленного взаимодействия, таких как приложение, рассматриваемое в этой статье.
  • services-config.xml: конфигурационный файл верхнего уровня, содержащий ссылки на все остальные файлы, а также настройки безопасности, параметры каналов и журналирования.

В листинге 6 показано содержимое файла services-config.xml. Обратите внимание на то, что в нашем приложении используется только один файл – remoting-config.xml, поскольку мы работаем только с сервисом удаленного взаимодействия BlazeDS.


Листинг 6. Конфигурационный файл services-config.xml
	
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
  <services>
    <service-include file-path="remoting-config.xml" />
    <service-include file-path="messaging-config.xml" />
    <service-include file-path="proxy-config.xml" />
    <default-channels>
       <channel ref="contacts-amf"/>
    </default-channels>
  </services>

  <channels>
    <channel-definition id="contacts-amf" class="mx.messaging.channels.AMFChannel">
      <endpoint url="http://localhost:8080/contacts/messagebroker/amf"
        class="flex.messaging.endpoints.AMFEndpoint"/>
      <properties>
        <polling-enabled>false</polling-enabled>
      </properties>
    </channel-definition>
  </channels>

  <logging>
    <target class="flex.messaging.log.ConsoleTarget" level="Error">
      <properties>
        <prefix>[BlazeDS] </prefix>
        <includeDate>false</includeDate>
        <includeTime>false</includeTime>
        <includeLevel>false</includeLevel>
        <includeCategory>false</includeCategory>
      </properties>
      <filters>
        <pattern>Endpoint.*</pattern>
        <pattern>Service.*</pattern>
        <pattern>Configuration</pattern>
      </filters>
    </target>
  </logging>

</services-config>

Конфигурационный файл services-config.xml ссылается на другие конфигурационные файлы (которые должны существовать), а также настраивает систему журналирования BlazeDS и несколько каналов. Канал – это абстракция протокола, используемого для взаимодействия клиента с сервером. В приложении этой статьи используется стандартный протокол AMF без опроса. Опрос означает, что клиенты постоянно взаимодействуют с сервером с целью убедиться, что соединение не разорвано. В нашем приложении этого не требуется.

Присоединяйтесь к сообществу Web-разработчиков портала My developerWorks

Принимайте участие в обсуждении различных вопросов и обменивайтесь информацией с другими разработчиками Web-приложений в группе Web-разработчиков портала My developerWorks.

Еще не являетесь участником My developerWorks? Присоединяйтесь сейчас!

С помощью конечной точки канала задается URL-адрес сервера. Для успешной компиляции проекта всегда должна быть указана конечная точка; клиентское Flash-приложение использует ее в качестве жестко заданного значения, определяющего сервер, к которому необходимо подключаться. На практике URL-адрес конечной точки можно задать непосредственно в коде MXML или ActionScript.

Наконец, в конфигурационном файле remoting-config.xml (листинг 7) указывается класс адаптера, необходимого для обработки операций удаленного взаимодействия, а также классы, отвечающие на удаленные вызовы (в нашем случае классом, отвечающим на удаленные запросы, является класс bcit.contacts.ContactsService).


Листинг 7. Конфигурационный файл remoting-config.xml
	
<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service"
  class="flex.messaging.services.RemotingService">

  <adapters>
    <adapter-definition id="java-object" default="true"
      class="flex.messaging.services.remoting.adapters.JavaAdapter"/>
  </adapters>

  <default-channels>
    <channel ref="contacts-amf"/>
  </default-channels>

  <destination id="contacts">
    <properties>
      <source>bcit.contacts.ContactsService</source>
      <!--<scope>application</scope>-->
    </properties>
  </destination>

</service>


Заключение

В этой статье было продемонстрировано, как написать Web-приложение, работающее на стороне Java-сервера под управлением Tomcat и отвечающее на запросы для получения контактной информации. Вы также узнали, как с помощью MXML и ActionScript написать Flex-приложение, работающее на стороне клиента. В качестве хранилища данных мы использовали MySQL, а преобразование Java-объектов в SQL-запросы осуществлялось с помощью ORM-инфраструктуры Hibernate. Наконец, инфраструктура BlazeDS позволяет Flash-приложениям осуществлять удаленные вызовы процедур и получать удаленный доступ к Web-приложениям, запущенным на стороне Java-сервера.



Загрузка

ИмяРазмерМетод загрузки
JEE-BlazeDS-Flex-contacts.zip7 МБHTTP

Информация о методах загрузки

Другие файлы для загрузки

Заметка

  1. В zip-архиве содержится весь исходный код (Java, ActionScript 3, MXML) рассмотренного проекта, build-файл Ant для генерации WAR, конфигурационные файлы, а также сторонние библиотеки (в виде JAR-файлов), которые были использованы в этой статье.
  2. Для работы рассмотренного в этой статье приложения требуется СУБД с открытым исходным кодом.
  3. Java-инструментарий для компоновки проекта.
  4. Для компиляции исходного Java-кода необходимо использовать набор средств разработки Java SDK (JDK) версии 6.
  5. Для компиляции исходного кода MXML и ActionScript необходимо использовать набор средств разработки Flex 4 SDK.
  6. Контейнер сервлетов, разработанный компанией Apache Software Foundation и представляющий собой серверную среду для выполнения Web-приложений Java.
  7. Инфраструктура Adobe для связывания технологии Flex с платформой Java Platform, Enterprise Edition (Java EE). Это программное обеспечение уже включено в состав загружаемого zip-архива проекта, и его не нужно загружать отдельно.
  8. Разработанная компанией Red Hat ORM-инфраструктура, предназначенная для поддержки контейнеров Java EE Middleware. Это программное обеспечение уже включено в состав загружаемого zip-архива проекта, и его не нужно загружать отдельно.

Ресурсы

Об авторе

Аррон Фергюсон (Arron Ferguson) в течение 12 лет преподавал программирование в технологическом институте Британской Колумбии. Его профессиональные интересы и опыт охватывают такие области, как Java, XML, Web-технологии, анимация (2D и 3D), и создание объектов цифровой мультимедиа. Он также имеет опыт работы независимым техническим редактором и рецензентом, а также является автором книги "Создание систем управления контентом в Java" (Charles River Media, 2006 г.). Наконец, Аррон является горячим сторонником Linux и программного обеспечения с открытым кодом.

Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Спасибо. Эта запись была помечена для модератора.


Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Сообщение о нарушении не было отправлено. Попробуйте, пожалуйста, позже.


developerWorks: вход


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Выберите ваше отображаемое имя

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

(Должно содержать от 3 до 31 символа.)


Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Оценить эту статью

Комментарии

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=SOA и web-сервисы, Технология Java, Open source
ArticleID=760677
ArticleTitle=Создание Web-приложений на базе Flex 4 и Java
publish-date=09212011
author1-email=arron_ferguson@bcit.ca
author1-email-cc=dwxed@us.ibm.com

Теги

Help
Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Используйте ползунок, чтобы отразить больше или меньше тегов.

КнопкаПопулярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere).

Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).

Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Кнопка Популярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere). Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).