Статьи

Пример ConversationScoped для Java EE CDI

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

ConversationScoped — это bean-компонент, область действия которого описывает взаимодействие пользователя с приложением JavaServer Faces в рамках явных контролируемых разработчиком границ, которые расширяют область действия для нескольких вызовов жизненного цикла JavaServer Faces. Все длительные разговоры ограничиваются определенным сеансом сервлета HTTP и могут не пересекать границы сеанса.

С bean-компонентами ConversationScoped мы можем достичь той же функциональности, которая нам необходима от bean-компонента ViewScoped JSF. Кроме того, с помощью beans- ConversationScoped мы можем поддерживать один и тот же диалог или состояние между различными запросами страниц. Но когда мы оставляем разговор без него, управляемый компонент остается активным до истечения времени ожидания.

Здесь мы создадим веб-приложение JFS, которое использует bean-компонент ConversationScoped для обеспечения диалога между клиентом и сервером. Клиент будет делать несколько запросов к серверу, переходя на отдельные страницы, чтобы показать, как компонент может поддерживать состояние.

Нашей предпочтительной средой разработки является Eclipse . Мы используем версию Eclipse Juno (4.2) вместе с плагином Maven Integration версии 3.1.0. Вы можете скачать Eclipse отсюда и Maven Plugin для Eclipse отсюда . Установка плагина Maven для Eclipse выходит за рамки данного руководства и не будет обсуждаться. Tomcat 7 — это используемый сервер приложений.

Давайте начнем,

1. Создайте новый проект Maven

Перейдите в Файл -> Проект -> Maven -> Проект Maven.

New-Maven-проект

На странице мастера «Выберите имя проекта и местоположение» убедитесь, что опция «Создать простой проект (пропустить выбор архетипа») не отмечена , нажмите «Далее», чтобы продолжить со значениями по умолчанию.

новый проект

Здесь должен быть добавлен архетип maven для создания веб-приложения. Нажмите «Добавить архетип» и добавьте архетип. Установите переменную «Archetype Group Id» на "org.apache.maven.archetypes" , переменную «Archetype ardact Id» на "maven-archetype-webapp" и «Archetype Version» на "1.0" . Нажмите «ОК», чтобы продолжить.

Maven-архетип-WebApp

На странице мастера «Введите идентификатор артефакта» вы можете определить имя и основной пакет вашего проекта. Установите для переменной «Group Id» значение "com.javacodegeeks.snippets.enterprise" а для переменной «Artifact Id» — "cdibeans" . Вышеупомянутые варианты составляют основной пакет проекта как "com.javacodegeeks.snippets.enterprise.cdibeans" а имя проекта — "cdibeans" . Установите для переменной «Package» значение "war" , чтобы создать файл war для развертывания на сервере tomcat. Нажмите «Готово», чтобы выйти из мастера и создать свой проект.

newcdiproject1

Структура проекта Maven показана ниже:

newcdiproject2

    Он состоит из следующих папок:

  • Папка / src / main / java, которая содержит исходные файлы для динамического содержимого приложения,
  • Папка / src / test / java содержит все исходные файлы для модульных тестов,
  • Папка / src / main / resources содержит файлы конфигурации,
  • Папка / target содержит скомпилированные и упакованные результаты,
  • Папка / src / main / resources / webapp / WEB-INF содержит дескрипторы развертывания для веб-приложения,
  • pom.xml — это файл объектной модели проекта (POM). Единственный файл, который содержит все связанные с проектом конфигурации.

2. Добавьте все необходимые зависимости

Вы можете добавить зависимости в файле Maven pom.xml , отредактировав его на странице «Pom.xml» редактора POM, как показано ниже:

pom.xml:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.javacodegeeks.snippets.enterprise.cdi</groupId>
    <artifactId>cdibeans</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>cdibeans Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>org.jboss.weld.servlet</groupId>
            <artifactId>weld-servlet</artifactId>
            <version>1.1.10.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.faces</artifactId>
            <version>2.1.7</version>
        </dependency>
    </dependencies>
 
    <build>
        <finalName>cdibeans</finalName>
    </build>
</project>

Как видите, Maven декларативно управляет библиотечными зависимостями. Создается локальный репозиторий (по умолчанию в папке {user_home} /. M2), и все необходимые библиотеки загружаются и помещаются туда из общедоступных репозиториев. Кроме того, внутрибиблиотечные зависимости автоматически разрешаются и обрабатываются.

3. Создайте Beans-объект Conversation

Класс CDIConversationScopedBean.java — это объект ConversationScoped , @ConversationScoped как @ConversationScoped . Ему дается имя cDIConversationScopedBean в контейнере с аннотацией @Named . Прежде всего, класс должен реализовывать интерфейс Serializable , чтобы быть управляемым компонентом ConversationScoped . Он также должен использовать интерфейс Conversation , который внедряется в bean-компонент, с аннотацией @Inject . Экземпляр Conversation внедряется в bean-компонент, чтобы позволить приложению управлять контекстом беседы, помечая текущий диалог как временный или длительный и указывая идентификатор беседы (уникальный идентификатор беседы).

Класс имеет свойство String, называемое message , а также методы getter и setter для этого свойства. Метод init() , аннотированный аннотацией @PostConstruct — это метод, который вызывается при создании компонента и initializes свойства сообщения.

initConversation() и endConversation() — это те, которые начинают и заканчивают диалог. Метод initConversation() помечает переходный conversation как длительный, тогда как метод endConversation() помечает длительный conversation как переходный, возвращаясь к начальной странице приложения. Если диалог находится в переходном состоянии в конце запроса JSF, он уничтожается, и контекст диалога также уничтожается. Если в конце запроса JSF диалог находится в состоянии длительного выполнения, он не уничтожается. Вместо этого он может распространяться на другие запросы. Все длительные разговоры имеют строковый уникальный идентификатор.

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

CDIConversationScopedBean.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.javacodegeeks.snippets.enterprise.cdibeans;
 
import java.io.Serializable;
import java.util.Random;
 
import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
 
@Named(value="cDIConversationScopedBean")
@ConversationScoped
public class CDIConversationScopedBean implements Serializable {
 
    private static final long serialVersionUID = -6541718762358561835L;
 
    @Inject
    private Conversation conversation;
     
    private String message;
     
    private String[] words = {"Hello!!","Have a nice day!!","Goodbye..","Hi!","Goodmorning!","Bye..","Good evening.."};
 
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
 
    public Conversation getConversation() {
        return conversation;
    }
 
    @PostConstruct
    public void init(){
        message = "Hello from the JavaCodeGeeks..";
    }
     
    public void initConversation(){
        if (!FacesContext.getCurrentInstance().isPostback()
            && conversation.isTransient()) {
             
            conversation.begin();
        }
    }
     
    public void sendMessage(){
        message = words[new Random().nextInt(7)];
    }
     
    public String next(){
        return "secondpage?faces-redirect=true";
    }
     
    public String endConversation(){
        if(!conversation.isTransient()){
            conversation.end();
        }
        return "firstpage?faces-redirect=true";
    }
     
}

4. Создайте страницы

Первая страница — это начальная страница, которая будет вызываться клиентом для начала разговора. Он устанавливает PreRenderViewEvent , который запускается до отображения страницы. PreRenderViewEvent вызывает метод bean-компонента initConversation() чтобы пометить диалог как длительный. На странице отображается свойство message bean-компонента, и каждый раз, когда нажимается кнопка «Get your message», message изменяется. При нажатии на кнопку «Продолжить с этим сообщением» вызывается ссылка метод next() компонента, и клиент перенаправляется на вторую страницу.

firstPage.xhtml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
    xmlns:f="http://java.sun.com/jsf/core">
<f:event listener="#{cDIConversationScopedBean.initConversation}"
    type="preRenderView"></f:event>
<h:head>
    <title>JCG conversation 1</title>
</h:head>
<h:body>
    <h:outputText value="Starting conversation"></h:outputText>
    <br />
    <br />
    <h:form>
        <h:outputText value="#{cDIConversationScopedBean.message}"></h:outputText>
        <br />
        <h:commandButton value="Get your message" type="submit">
            <f:ajax execute="@form"
                listener="#{cDIConversationScopedBean.sendMessage}" render="@form" />
        </h:commandButton>
        <br />
        <br />
        <h:commandLink action="#{cDIConversationScopedBean.next}"
            value="Continue with this message" />
    </h:form>
</h:body>
</html>

На второй странице снова отображается значение message , которое было выбрано клиентом на предыдущей странице. Нажав на ссылку «Давайте закончим разговор», клиент перенаправляется на третью страницу.

secondPage.xhtml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
    xmlns:f="http://java.sun.com/jsf/core">
<h:head>
    <title>JCG conversation 2</title>
</h:head>
<h:body>
    <h:outputText value="Continuing.."></h:outputText>
    <br />
    <br />
    <h:outputText value="#{cDIConversationScopedBean.message}"></h:outputText>
    <br />
    <br />
    <h:link outcome="/thirdpage.xhtml" value="Let's end the converation">
        <f:param name="cid" value="#{cDIConversationScopedBean.conversation.id}" />
    </h:link>
</h:body>
</html>

На третьей странице снова отображается значение message . При щелчке по endConversation() «Завершить разговор» endConversation() метод bean-компонента endConversation() который перенаправляет клиента на первую страницу, устанавливая conversation как переходный.

thirdPage.xhtml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
    xmlns:f="http://java.sun.com/jsf/core">
<h:head>
    <title>JCG conversation 3</title>
</h:head>
<h:body>
    <h:outputText value="Ending conversation"></h:outputText>
    <br />
    <br />
    <h:outputText value="#{cDIConversationScopedBean.message}"></h:outputText>
    <br />
    <br />
    <h:form>
        <h:commandLink action="#{cDIConversationScopedBean.endConversation}"
            value="End conversation" />
    </h:form>
</h:body>
</html>

5. Настройте web.xml

В веб-приложении web.xml — это файл, который определяет все о приложении, которое должен знать сервер. Здесь устанавливаются сервлеты и другие компоненты, такие как фильтры или прослушиватели, параметры инициализации, ограничения безопасности, управляемые контейнером, ресурсы, страницы приветствия и т. Д. В приложении JFS нам нужно определить в файле web.xml javax.faces.webapp.FacesServlet , который является классом, отвечающим за обработку приложений JSF. FacesServlet — это центральный контроллер для приложения JSF. Он получает все запросы для приложения JSF и инициализирует компоненты JSF до отображения JSP. Итак, в файле web.xml есть запись, которая определяет FacesServlet . Это запись servlet . Он также имеет запись servlet-mapping , чтобы отобразить все запросы, URL которых заканчивается на .xhtml который должен обрабатываться сервлетом. Здесь мы также указываем прослушиватель сервлета (используется для загрузки Weld и управления его взаимодействием с запросами).

web.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    id="WebApp_ID" version="3.0">
 
    <display-name>CDI Web Application</display-name>
 
    <listener>
        <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
    </listener>
    <servlet>
        <servlet-name>faces</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>faces</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
 
</web-app>

6. Запустите приложение

Чтобы запустить приложение, нам нужно собрать проект с Maven. Созданный файл war должен быть помещен в папку webapps tomcat. Тогда мы можем нажать на:

локальный: 8080 / cdibeans / firstpage.xhtml

в браузере, и результат показан ниже:

CONV1

Нажав на кнопку «Получить ваше сообщение», мы можем изменить message , как показано ниже:

conv2

Нажав на ссылку «Продолжить с этим сообщением», мы переходим на следующую страницу, сохраняя значение message .

conv3

Нажав на ссылку «Давайте закончим разговор», мы переходим на следующую страницу, и значение message сохраняется.

conv4

Теперь, если мы нажмем на ссылку «Завершить разговор», разговор закроется, и снова отобразится первая страница, начиная новый разговор.

Это было учебное пособие по Java EE CDI ConversationScoped Bean.

Загрузите исходный код этого учебника: CDIConversationScopedBeansExample.zip