Caché + Java + Flex. Часть 2

В первой части статьи мы рассмотрели комбинацию Caché + Java. Здесь будет показана структура проекта непосредственно реализующего комбинацию Caché + Java + Flex, а также основные инструменты и их настройки, используемые для её реализации. Стоит отметить, что здесь будет приведен лишь общий вид взаимодействия, в то время как, конкретные примеры будут рассмотрены в заключительной части. Начнем с описания модулей, входящих в состав проекта, и постепенно перейдем к особенностям их взаимодействия.

Структура проекта

Проект состоит из трёх основных модулей:

  1. flex – здесь располагаются mxml-классы, описывающие структуру web-интерфейса, дополнительные библиотеки на ActionScript, а также сгенерированные ActionScript-проекции java-классов;
  2. biz-logic – включает java -c и -m классы (подробнее о данных классах было рассказано в первой части статьи), класс контроллер, а так же классы-интерфейсы, отвечающие за логику приложения;
  3. web-application – генерируемый модуль, хранящий сформированные jar-файлы из модуля biz-logic и swf из модуля flex. Кроме этого, данный модуль отвечает за генерацию WAR (Web application ARchive), который позже размещается на web-сервере.


Далее стоит сказать несколько слов о применяемых инструментах. В качестве web-сервера был использован Apache Tomcat версии 6.0.35. Как было отмечено в первой части, в качестве основного инструмента для связи Java и ActionScript используется фреймворк Granite DS, представляющий комплексное решение для разработки и интеграции flex + javaEE RIA приложений. Его необходимо подключать как в настройках для flex, так и biz-logic модулей (как это сделать, будет рассказано дальше). Для автоматизации сборки проекта выбран Maven – универсальный инструмент для сборки Java проектов (компиляции, создания jar, создания дистрибутива программы, генерации документации). Maven, по умолчанию, создает по отдельному POM (Project Object Model) файлу для каждого из модулей, а также один общий для всего проекта. POM файлы используются для настройки конфигурации, а также для подключения библиотек из репозиториев (подробнее о работе с Maven можно прочитать здесь, а также работа с Maven подробно рассматривалась на Хабре). Приведем примеры некоторых настроек, использованных нами.

Содержание POM-файлов

Рассмотрим подробнее особенности POM-файлов для каждого из модулей проекта. В POM-файл модуля flex прописываются настройки Granite DS и пути к java-классам, проекции которых необходимо создать. Кроме этого здесь же привязываются используемые библиотеки. К примеру, данный код служит для указания файлов для проецирования, а так же содержит ряд настроек для GraniteDS.

<execution>
    <goals>
        <goal>generate</goal> <!—цель генерация-->
    </goals>
    <configuration>
      <generatorToUse>graniteds21</generatorToUse> <!—используемый генератор-->
      <baseOutputDirectory>${project.build.directory}/generated- sources</baseOutputDirectory> <!—выходная директория для проекций-->
      <outputDirectory>${project.build.directory}/../src/main/flex </outputDirectory> <!—выходная директория для классов наследующих от проекций-->
         <extraOptions>
           <tide>true</tide>
           <uid>uid</uid>
           <entityFactory>org.granite.generator.as3.BVEntityFactory </entityFactory>
           <outputEnumToBaseOutputDirectory>false </outputEnumToBaseOutputDirectory>
         </extraOptions>
         <includeJavaClasses>
           <include>edu.samples.sample.domain.**</include> <!—путь к классам, проекции которых необходимо сгенерировать-->
           <include>edu.samples.sample.services.I*Service</include> <!—путь к интерфейсам, проекции которых необходимо сгенерировать -->
         </includeJavaClasses>
    </configuration>
</execution>

Следующий код так же располагается в POM-файле модуля flex и демонстрирует подключение библиотек Granite из репозитория:

<dependency>
  <!—основные координаты библиотеки-->
  <groupId>org.graniteds</groupId>
  <artifactId>granite-core</artifactId>
  <!—версия файла библиотеки-->
  <version>${graniteds.version}</version>
</dependency>

В POM-файле для модуля biz-logic указываются параметры для генерации jar-файлов.

Кроме этого, необходимо подключить библиотеки cachedb и cachejdbc для работы с Caché (данные библиотеки в виде jar-файлов предоставляются вместе с продуктами Ensemble и Caché. По умолчанию располагаются в “dev\java\lib\JDK16\”).
В нашем случае файлы библиотек указаны локально:

<dependency> <!—зависимости (библиотеки) используемые для сборки-->
  <groupId>cache.cachedb</groupId><!—основные координаты библиотеки-->
  <artifactId>cachedb</artifactId>
  <type>jar</type> <!—тип файла библиотеке-->
  <version>${cachedb.version}</version> <!—версия файла библиотеки-->
  <scope>system</scope> <!—назначение библиотеки-->
  <systemPath>C:/soft/javalibs/cachedb.jar</systemPath> <!—путь к файлу-библиотеке-->
</dependency>
<dependency>
  <groupId>cache.cachejdbc</groupId>
  <artifactId>cachejdbc</artifactId>
  <version>${cachejdbc.version}</version>
  <type>jar</type>
  <scope>system</scope>
  <systemPath>C:/soft/javalibs/cachejdbc.jar</systemPath>
</dependency>

В POM-файле для модуля web-application прописываются привязка сгенерированных ранее в модуле biz-logic jar-файлов и опции для генерации WAR-файла такие как: output-директория для сгенерированного файла, подключение библиотек war-компилятора (maven-compiler-plugin, maven-war-plugin, maven-dependency-plugin). Так же должны быть прописаны опции для генерации swf-файла.
Настройка модуля web-application

<plugin>
  <!—основные координаты плагина в репозитории-->
  <groupId>org.sonatype.flexmojos</groupId>
  <artifactId>flexmojos-maven-plugin</artifactId>
  <version>${flexmojos.version}</version>
  <configuration>
     <stripVersion>true</stripVersion>
  </configuration>
  <executions>
    <execution>
      <goals>
       <goal>copy-flex-resources</goal> <!—цель копирование флекс ресурсов-->
      </goals>
      <configuration>
        <artifactItems>
          <artifactItem>
          <!—основные координаты файлов для копирования в swf-->
            <groupId>edu.sample</groupId>
            <artifactId>flex</artifactId>
            <type>swf</type> <!—тип генерируемого файла swf-->
            <overWrite>true</overWrite> <!—перезаписать существующий-->
            <destFileName>sample.swf</destFileName><!— имя сгенерированного файла-->
          </artifactItem>
        </artifactItems>
      </configuration>
    </execution>
  </executions>
</plugin>

Порядок сборки проекта следующий: компилируются java-классы из модуля biz-logic, затем на их основе с помощью GraniteDS генерируются ActionScript-проекции, которые помещаются в модуль flex. После этого компилируется модуль flex и с помощью плагина org.sonatype.flexmojos (предоставляется Flex) генерируется .swf файл. Он вместе с используемыми библиотеками помещается на сервер по прописанному в конфигурационном файле пути. На основе сгенерированных .swf и .jar файлов, а также используемых библиотек формируется .war файл.
Настройка .war файла

<properties> <!—опции для генерации-->
  <war.name>sample</war.name><!—имя сгенерированного war-файла-->
  <catalina.home>C:\Program Files\Apache Software Foundation\Tomcat 
  6.0</catalina.home> <!--путь к серверу, на котором будет размещен war-->
  <skipTests>true</skipTests>
</properties>

<build>
  <finalName>sample</finalName>
  <testSourceDirectory>src/test/java</testSourceDirectory>
  <plugins>
    <!--подключение плагина для компиляции-->
    <plugin> 
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <sourсe>1.6</sourсe>
        <target>1.6</target>
      </configuration>
    </plugin>
    <!—подключения плагина для генерации war-->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <configuration>
        <warName>${war.name}</warName>
      </configuration>
    </plugin>
      <!—подключение плагина определяющего зависимости-->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <version>2.1</version>
      <executions>
        <execution>
          <id>copy</id>
          <phase>install</phase>
          <goals>
            <goal>copy</goal>
          </goals>
          <configuration>
            <artifactItems>
              <artifactItem>
                <groupId>edu.sample</groupId>
                <artifactId>web-application</artifactId>
                <version>1.0</version>
                <type>war</type>
                <overWrite>true</overWrite>
                <destFileName>${war.name}.war</destFileName>
                <outputDirectory>${catalina.home}\webapps\ 
                </outputDirectory>
              </artifactItem>
            </artifactItems>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

После того, как все настройки выполнены, можно приступать к непосредственному рассмотрению механизма взаимодействия Flex + Java + Caché.

Общий вид механизма взаимодействия Flex + Java + Caché

Начнём с того, что всё взаимодействие Flex + Java проходит через ActionScript-проекции, среди которых, кроме проекций хранимых классов (Java-m классы), есть и классы-проекции интерфейсов сервера, отвечающие за логику приложения. В момент запуска web-приложения в браузере (на стороне клиента) при инициализации создается объект, реализующий интерфейс сервисов сервера (в нашем случае это объект userService). Через него и будет в дальнейшем происходить связка flex + java. Для выполнения какой-либо операции над хранимыми объектами вызывается соответствующий метод в userService. В случае удачного прохождения определенных условий на сервере изменения также будут выполнены в БД Caché.

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

  1. Класс должен реализовывать интерфейс Serializable.
  2. В проецируемых классах должен использоваться специальный синтаксис Granite DS. Например, для методов get() и set() проецируемых свойств нужно использовать теги @ExternalizedProperty, а для самого проецируемого класса – @ExternalizedBean, как показано в примере ниже.
@ExternalizedBean(type=DefaultExternalizer.class)
public class mCicl  implements Serializable {
    …
    @ExternalizedProperty
    public List<mDiscipline> getListOfDisc() {
        return listOfDisc;
    }
    public void setListOfDisc(List<mDiscipline> listOfDisc) {
        this.listOfDisc = listOfDisc;
    }
    …
}

Не стоит также забывать о java-нотации. Так, к примеру, при именовании свойства с заглавной буквы в проекции, данное свойство будет иметь модификатор доступа private без get и set методов.

Как уже говорилось выше, в модуле flex используется интерфейс (@RemoteDestination) сервисов (@Serviсe) сервера, поэтому в модуле biz-logic должна быть соответствующая реализация данного интерфейса. Например, для проецируемого класса-интерфейса

@RemoteDestination
public interface IUserService {
…
void delOneDisc(Integer i);
…
}

должна быть прописана реализация

@Service
public class UserService implements IUserService {
…
    @Override
    public void delOneDisc(Integer i) {
        objT.deleteOneDisc(i);
    }
…
}

Подводя итоги данной части, можно сказать, что здесь мы описали лишь общий механизм взаимодействия Caché + Java + Flex через интерфейсы и проекции, а также необходимые для них настройки, не заостряя внимания на конкретных примерах. Поэтому в следующей части статьи мы уделим больше внимания конкретным практическим примерам. В частности рассмотрим преобразования коллекций на протяжении всей связки, а также примеры передачи объектов от БД до браузера и обратно.

Caché + Java + Flex. Часть 2: 1 комментарий

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *