Java Platform, Enterprise Edition (Java EE) 8
Учебник по Java EE

Назад Вперёд Содержание

Пример cart

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

  • Класс сессионного компонента (CartBean)

  • Удалённый бизнес-интерфейс (Cart)

Все сессионные компоненты имеют соответствующий им класс Java. Все Enterprise-бины, которые разрешают удалённый доступ, должны иметь удалённый бизнес-интерфейс. Для удовлетворения потребностей конкретного приложения Enterprise-бину также могут потребоваться некоторые вспомогательные классы. Сессионный компонент CartBean использует два вспомогательных класса — BookException и IdVerifier, которые обсуждаются в разделе Вспомогательные классы.

Исходный код для этого примера находится в каталоге tut-install/examples/ejb/cart/.

Бизнес-интерфейс

Бизнес-интерфейс Cart — это интерфейс Java, который определяет все бизнес-методы, реализованные в классе компонента. Если класс бина реализует один интерфейс, этот интерфейс считается бизнес-интерфейсом. Бизнес-интерфейс является локальным интерфейсом, если он не помечен аннотацией javax.ejb.Remote. Аннотация javax.ejb.Local в этом случае необязательна.

Класс бина может реализовывать более одного интерфейса. В этом случае бизнес-интерфейсы должны быть либо явно аннотированы @Local или @Remote, либо указаны путём аннотирования класса компонента аннотациями @Local или @Remote. Однако следующие интерфейсы исключаются при определении того, реализует ли класс бина более одного интерфейса:

  • java.io.Serializable

  • java.io.Externalizable

  • Любой из интерфейсов, определённых пакетом javax.ejb

Исходный код бизнес-интерфейса Cart выглядит следующим образом:

package javaeetutorial.cart.ejb;

import cart.util.BookException;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface Cart {
    public void initialize(String person) throws BookException;
    public void initialize(String person, String id) throws BookException;
    public void addBook(String title);
    public void removeBook(String title) throws BookException;
    public List<String> getContents();
    public void remove();
}

Класс сессионного бина

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

  • Класс аннотирован @Stateful.

  • Класс реализует бизнес-методы, определённые в бизнес-интерфейсе.

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

  • Реализовать бизнес-интерфейс — интерфейс Java Реализовать бизнес-интерфейс — хорошая практика.

  • Реализовать любые дополнительные Callback-методы жизненного цикла, аннотированные @PostConstruct, @PreDestroy, @PostActivateи @PrePassivate.

  • Реализовать любые необязательные бизнес-методы, аннотированные @Remove.

Исходный код для класса CartBean выглядит следующим образом:

package javaeetutorial.cart.ejb;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javaeetutorial.cart.util.BookException;
import javaeetutorial.cart.util.IdVerifier;
import javax.ejb.Remove;
import javax.ejb.Stateful;

@Stateful
public class CartBean implements Cart {
    String customerId;
    String customerName;
    List<String> contents;

    @Override
    public void initialize(String person) throws BookException {
        if (person == null) {
            throw new BookException("Null person not allowed.");
        } else {
            customerName = person;
        }
        customerId = "0";
        contents = new ArrayList<>();
    }

    @Override
    public void initialize(String person, String id)
                 throws BookException {
        if (person == null) {
            throw new BookException("Null person not allowed.");
        } else {
            customerName = person;
        }

        IdVerifier idChecker = new IdVerifier();
        if (idChecker.validate(id)) {
            customerId = id;
        } else {
            throw new BookException("Invalid id: " + id);
        }

        contents = new ArrayList<>();
    }

    @Override
    public void addBook(String title) {
        contents.add(title);
    }

    @Override
    public void removeBook(String title) throws BookException {
        boolean result = contents.remove(title);
        if (result == false) {
            throw new BookException("\"" + title + " not in cart.");
        }
    }

    @Override
    public List<String> getContents() {
        return contents;
    }

    @Remove
    @Override
    public void remove() {
        contents = null;
    }
}

Callback-методы жизненного цикла

Метод в классе бина может быть объявлен как Callback-метод жизненного цикла, добавлением в метод следующих аннотаций.

  • javax.annotation.PostConstruct: методы, аннотированные с помощью @PostConstruct, вызываются контейнером для вновь созданных объектов бинов после завершения инъецирования всех зависимостей и до вызова первого бизнес-метода в Enterprise-бине.

  • javax.annotation.PreDestroy: методы, аннотированные с помощью @PreDestroy, вызываются после завершения любого аннотированного @Remove метода и перед удалением Enterprise-бина контейнером.

  • javax.ejb.PostActivate: методы, помеченные @PostActivate, вызываются контейнером после того, как контейнер перемещает компонент из вторичного хранилища в активное состояние.

  • javax.ejb.PrePassivate: методы, аннотированные @PrePassivate, вызываются контейнером до его пеактивации Enterprise-бином, то есть контейнер временно удаляет бин из среды и сохраняет его во вторичное хранилище.

Callback-методы жизненного цикла должны возвращать void и не иметь параметров.

Бизнес-методы

Основная цель сессионного компонента — запуск бизнес-задач для клиента. Клиент вызывает бизнес-методы для ссылки на объект, который он получает при инъецирования зависимости или поиске JNDI. С точки зрения клиента, бизнес-методы работают локально, хотя они выполняются удалённо в сессионном компоненте. В следующем фрагменте кода показано, как программа CartClient вызывает бизнес-методы:

cart.initialize("Duke DeEarl", "123");
...
cart.addBook("Bel Canto");
 ...
List<String> bookList = cart.getContents();
...
cart.removeBook("Gravity's Rainbow");

Класс CartBean реализует бизнес-методы в следующем коде:

@Override
public void addBook(String title) {
   contents.add(title);
}

@Override
public void removeBook(String title) throws BookException {
   boolean result = contents.remove(title);
   if (result == false) {
      throw new BookException("\"" + title + "not in cart.");
   }
}

@Override
public List<String> getContents() {
   return contents;
}

Сигнатура бизнес-метода должна соответствовать следующим правилам.

  • Имя метода не должно начинаться с ejb, чтобы избежать конфликтов с Callback-методами, определёнными архитектурой EJB. Например, вы не можете вызвать бизнес-метод ejbCreate или ejbActivate.

  • Модификатор доступа должен быть public.

  • Если бин разрешает удалённый доступ через удалённый бизнес-интерфейс, аргументы и возвращаемые типы должны быть допустимыми типами для API удалённого вызова методов Java (RMI).

  • Если бин является конечной точкой веб-сервиса JAX-WS, аргументы и возвращаемые типы для аннотированных методов @WebMethod должны быть допустимыми типами для JAX-WS.

  • Если бин является ресурсом JAX-RS, аргументы и возвращаемые типы для методов ресурса должны быть допустимыми типами для JAX-RS.

  • Модификатор не должен быть static или final.

Предложение throws может содержать исключения, которые вы определяете для своего приложения. Например, метод removeBook выдает BookException, если книга отсутствует в корзине.

Чтобы указать на проблему на уровне системы, например невозможность подключения к базе данных, бизнес-метод может выбросить javax.ejb.EJBException. Контейнер не будет обёртывать (wrap) исключения приложения, такие как BookException. Поскольку EJBException является дочерним классом RuntimeException, вам не нужно добавлять его в throws бизнес-метода.

Метод @Remove

Бизнес-методы, аннотированные javax.ejb.Remove в классе сессионного компонента с сохранением состояния, могут вызываться клиентами Enterprise-бина для удаления объекта компонента. Контейнер удалит Enterprise-бин после завершения метода @Remove независимо от того, завершился он нормально или с ошибкой.

В CartBean метод remove помечен аннотацией @Remove:

@Remove
@Override
public void remove() {
    contents = null;
}

Вспомогательные классы

Сессионный компонент CartBean имеет два вспомогательных класса: BookException и IdVerifier. BookException выбрасывается методом removeBook, а IdVerifier валидирует customerId в одном из методов create. Вспомогательные классы могут находиться в файле EJB JAR, который содержит класс Enterprise-бина. Или в WAR-файле, если Enterprise-бин упакован в WAR. Или EAR-файле, содержащем файл EJB JAR, WAR-файл или отдельный JAR-файл библиотеки. В cart вспомогательные классы включены в библиотечный JAR, используемый клиентским приложением, и EJB JAR.

Запуск cart

Теперь вы готовы скомпилировать удалённый интерфейс (Cart.java), класс Enterprise-бина (CartBean.java), клиентский класс (CartClient.java) и вспомогательные классы (BookException.java и IdVerifier.java).

Вы можете использовать IDE NetBeans или Maven для сборки, упаковки, развёртывания и запуска приложения cart.

Здесь рассматриваются следующие темы:

Запуск cart с IDE NetBeans

  1. Удостоверьтесь, чтобы GlassFish Server был запущен (см. Запуск и остановка сервера GlassFish).

  2. В меню «Файл» выберите «Открыть проект».

  3. В диалоговом окне «Открыть проект» перейдите к:

    tut-install/examples/ejb
  4. Выберите каталог cart.

  5. Установите флажок Открыть требуемые проекты.

  6. Нажмите Открыть проект.

  7. На вкладке «Проекты» кликните правой кнопкой мыши проект cart и выберите «Сборка».

    Это создаёт и упаковывает приложение в cart.ear, расположенный в tut-install/examples/ejb/cart/cart-ear/target/, и развёртывает этот файл EAR в ваш объект GlassFish Server.

    Вы увидите выходные данные приложения-клиента cart-app-client на вкладке Вывод:

    ...
    Retrieving book title from cart: Infinite Jest
    Retrieving book title from cart: Bel Canto
    Retrieving book title from cart: Kafka on the Shore
    Removing "Gravity's Rainbow" from cart.
    Caught a BookException: "Gravity's Rainbow" not in cart.

Запуск cart с помощью Maven

  1. Удостоверьтесь, чтобы GlassFish Server был запущен (см. Запуск и остановка сервера GlassFish).

  2. В окне терминала перейдите в:

    tut-install/examples/ejb/cart/
  3. Введите следующую команду:

    mvn install

    Эта команда компилирует и упаковывает приложение в файл EAR, cart.ear, расположенный в каталоге target, и развёртывает EAR в GlassFish Server.

    Затем клиентские заглушки извлекаются и запускаются. Это эквивалентно выполнению следующей команды:

    appclient -client cart-ear/target/cart-earClient.jar

    Клиентский JAR cart-earClient.jar содержит клиентский класс приложения, вспомогательный класс BookException и бизнес-интерфейс Cart.

    При запуске клиента контейнер клиентского приложения инъецирует все ссылки на компоненты, объявленные в классе клиентского приложения, в данном случае ссылку на Enterprise-бин Cart.

    В окне терминала вы увидите вывод cart-app-client:

    ...
    Retrieving book title from cart: Infinite Jest
    Retrieving book title from cart: Bel Canto
    Retrieving book title from cart: Kafka on the Shore
    Removing "Gravity's Rainbow" from cart.
    Caught a BookException: "Gravity's Rainbow" not in cart.

Назад Вперёд Содержание
Логотип Oracle  Copyright © 2017, Oracle и/или её дочерних компаний. Все права защищены. Версия перевода 1.0.5 (Java EE Tutorial — русскоязычная версия)