Статьи

JSF 2.2: поток вызовов


В этом уроке мы рассмотрим вызовы Faces Flow.
Чтобы получить базовый уровень информации о Faces Flow, ознакомьтесь с
этой статьей, а информацию об использовании потоков можно найти в
руководстве
JSF 2.2: Использование Faces Flow .

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

1. Структура каталогов проекта

Снимок экрана 2013-06-30 в 8.45.34 вечера

2. Зависимости проекта

<dependency>
   <groupId>javax</groupId>
   <artifactId>javaee-api</artifactId>
   <version>7.0-b72</version>
    <scope>provided</scope>
</dependency>
            
<dependency>
   <groupId>org.glassfish</groupId>
   <artifactId>javax.faces</artifactId>
   <version>2.2.0</version>
   <scope>provided</scope>
</dependency>

3. Customer.java

public class Customer implements Serializable {
    
    @Produces
    @FlowDefinition
    public Flow defineFlow(@FlowBuilderParameter FlowBuilder flowBuilder) {

        String flowId = "customer";
        flowBuilder.id("", flowId);
        flowBuilder.viewNode(flowId, "/" + flowId + "/" + flowId + ".xhtml").markAsStartNode();
        
        flowBuilder.returnNode("returnFromCustomerFlow")
                   .fromOutcome("#{customerBean.returnValue}");
       
        flowBuilder.inboundParameter("productOrder", "#{flowScope.productOrder}");
        flowBuilder.inboundParameter("priceOrder", "#{flowScope.priceOrder}");
        flowBuilder.inboundParameter("adressLine1Order", "#{flowScope.adressLine1Order}");
        flowBuilder.inboundParameter("adressLine2Order", "#{flowScope.adressLine2Order}");
        flowBuilder.inboundParameter("cityOrder", "#{flowScope.cityOrder}");
        flowBuilder.inboundParameter("stateOrder", "#{flowScope.stateOrder}");
        flowBuilder.inboundParameter("postalCodeOrder", "#{flowScope.postalCodeOrder}");
        flowBuilder.inboundParameter("countryOrder", "#{flowScope.countryOrder}");
        
        flowBuilder.flowCallNode("callOrder").flowReference("", "order")
                   .outboundParameter("firstNameCustomer", "#{customerBean.firstName}")
                   .outboundParameter("lastNameCustomer", "#{customerBean.lastName}")
                   .outboundParameter("adressLine1Customer", "#{customerBean.adressLine1}")
                   .outboundParameter("adressLine2Customer", "#{customerBean.adressLine2}")
                   .outboundParameter("cityCustomer", "#{customerBean.city}")
                   .outboundParameter("stateCustomer", "#{customerBean.state}")
                   .outboundParameter("postalCodeCustomer", "#{customerBean.postalCode}")
                   .outboundParameter("countryCustomer", "#{customerBean.country}");
        
        return flowBuilder.getFlow();
    }
}

Метод
InboundParameter корректирует имена и значения входящих параметров из потоков заказов.

Метод
FlowCallNode определяет, как поток клиента вызывает поток заказа. Аргумент «callOrder», который был передан методу, определяет
действие вызова потока . Прикован
flowReference Метод определяет фактическое имя потока для вызова.

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

Для объяснения оставшегося кода, вы можете проверить предыдущий
учебник

4. order-flow.xml

<flow-definition id="order">
        
        <flow-return id="returnFromOrderFlow">
            <from-outcome>#{orderBean.returnValue}</from-outcome>
        </flow-return>
                    
        <inbound-parameter>
            <name>firstNameCustomer</name>
            <value>#{flowScope.firstNameCustomer}</value>
        </inbound-parameter>
        <inbound-parameter>
            <name>lastNameCustomer</name>
            <value>#{flowScope.lastNameCustomer}</value>
        </inbound-parameter>
        <inbound-parameter>
            <name>adressLine1Customer</name>
            <value>#{flowScope.adressLine1Customer}</value>
        </inbound-parameter>
        <inbound-parameter>
            <name>adressLine2Customer</name>
            <value>#{flowScope.adressLine2Customer}</value>
        </inbound-parameter>
        <inbound-parameter>
            <name>cityCustomer</name>
            <value>#{flowScope.cityCustomer}</value>
        </inbound-parameter>
        <inbound-parameter>
            <name>stateCustomer</name>
            <value>#{flowScope.stateCustomer}</value>
        </inbound-parameter>
        <inbound-parameter>
            <name>postalCodeCustomer</name>
            <value>#{flowScope.postalCodeCustomer}</value>
        </inbound-parameter>
        <inbound-parameter>
            <name>countryCustomer</name>
            <value>#{flowScope.countryCustomer}</value>
        </inbound-parameter>
        
        <flow-call id="callCustomer">
            <flow-reference>
                <flow-id>customer</flow-id>
            </flow-reference>
            <outbound-parameter>
                <name>productOrder</name>
                <value>#{orderBean.product}</value>
            </outbound-parameter>
            <outbound-parameter>
                <name>priceOrder</name>
                <value>#{orderBean.price}</value>
            </outbound-parameter>
            <outbound-parameter>
                <name>adressLine1Order</name>
                <value>#{orderBean.adressLine1}</value>
            </outbound-parameter>
            <outbound-parameter>
                <name>adressLine2Order</name>
                <value>#{orderBean.adressLine2}</value>
            </outbound-parameter>
            <outbound-parameter>
                <name>cityOrder</name>
                <value>#{orderBean.city}</value>
            </outbound-parameter>
            <outbound-parameter>
                <name>stateOrder</name>
                <value>#{orderBean.state}</value>
            </outbound-parameter>
            <outbound-parameter>
                <name>postalCodeOrder</name>
                <value>#{orderBean.postalCode}</value>
            </outbound-parameter>
            <outbound-parameter>
                <name>countryOrder</name>
                <value>#{orderBean.country}</value>
            </outbound-parameter>
        </flow-call> 
 </flow-definition>  
           

В этом коде конфигурация XML аналогична программной конфигурации. Входящие параметры для потока заказа определяются с помощью
элемента
входящего параметра

Элементы потока вызовов определяют, как поток заказов будет вызывать поток клиентов. Аргумент callCustomer, который передается в атрибут ID элемента, определяет
действие вызова потока

Элементы ссылки на поток внутри элемента определяют фактическое имя потока для вызова. Когда вызывается поток клиента, передаваемые параметры определяются
элементом
outboundParameter

Для объяснения оставшихся частей конфигурации XML вы можете обратиться к предыдущему руководству. 

5. CustomerBean.java — OrderBean.java

@Named
@FlowScoped("customer")
public class CustomerBean implements Serializable {

    private String firstName;
    private String lastName;
    private String adressLine1;
    private String adressLine2;
    private String city;
    private String state;
    private String postalCode;
    private String country;
    
    
    public CustomerBean() {
        System.out.println("CustomerBean has been created...");
    }
    
    public String getName() {
        return this.getClass().getSimpleName();
    }

    public String getReturnValue() {
        return "/index";
    }
 
 /* getter and setter methods */
}

6. Демо-приложение