官术网_书友最值得收藏!

The conversation scope

The conversation scope allows developers to demarcate the lifespan of the session scope.

The conversation scope is committed to the user's interaction with JSF applications and represents a unit of work from the point of view of the user; a bean in this scope is able to follow a conversation with a user. We may charge the conversation scope as a developer-controlled session scope across multiple invocations of the JSF life cycle; while session scoped lives across unlimited requests, the conversation scopes lives only across a limited number of requests.

Note

The conversation scope bean might get passivated by the container and should be capable of passivity by implementing the java.io.Serializable interface.

The developer can explicitly set the conversation scope boundaries and can start, stop, or propagate the conversation scope based on the business logic flow. All long-running conversations are scoped to a particular HTTP servlet session and may not cross session boundaries. In addition, conversation scope keeps the state associated with a particular Web browser window/tab in a JSF application.

Note

The conversation scope annotation is @ConversationScoped and is defined in the javax.enterprise.context package for CDI. This scope is not available in JSF!

Dealing with the conversation scope is slightly different from the rest of the scopes. First, you mark the bean with @ConversationScope, represented by the javax.enterprise.context.ConversationScoped class. Second, CDI provides a built-in bean (javax.enterprise.context.Conversation) for controlling the life cycle of conversations in a JSF application—its main responsibility is to manage the conversation context. This bean may be obtained by injection, as shown in the following code:

private @Inject Conversation conversation;

By default, the Conversation object is in transient state and it should be transformed into a long-running conversation by calling the begin method. You also need to prepare for the destruction of the conversation by calling the end method.

Note

If we try to call the begin method when the conversation is active, or the end method when the conversation is inactive, IllegalStateException will be thrown. We can avoid this by testing the transitivity state of the Conversation objects using the method named isTransient, which returns a Boolean value.

Now, add the begin, end, and isTransient methods together to the following conversations:

  • For start conversation, the code is as follows:
    if (conversation.isTransient()) {
      conversation.begin();
    }
  • For stop conversation, the code is as follows:
    if (!conversation.isTransient()) {
      conversation.end();
    }

For example, you can add the conversation scope in PlayersBean as follows:

@Named
@ConversationScoped
public class PlayersBean implements Serializable {

 private @Inject
 Conversation conversation;

  final String[] players_list = {"Nadal, Rafael (ESP)","Djokovic, Novak (SRB)", "Ferrer, David (ESP)", "Murray, Andy (GBR)", "Del Potro, Juan Martin (ARG)"};
  private ArrayList players = new ArrayList();
  private String player;

  public PlayersBean() {
  }

  //getters and setters

  public void newPlayer() {
    int nr = new Random().nextInt(4);
    player = players_list[nr];
    players.add(player);
  }   

 public void startPlayerRnd() {
 if (conversation.isTransient()) {
 conversation.begin();
 }
 }

 public void stopPlayerRnd() {
 if (!conversation.isTransient()) {
 conversation.end();
 }
 }
}

Besides injecting the built-in CDI bean, notice that you have defined a method (startPlayerRnd) for demarcating the conversation start point and another method (stopPlayerRnd) for demarcating the conversation stop point. In this example, both the methods are exposed to the user through two buttons, but you can control the conversation programmatically by calling them conditionally.

Running the example inside a conversation will reveal something as shown in the following screenshot:

The list of randomly extracted players will be empty or will contain only the current extracted player until the button labeled Start Conversation is clicked. At that moment the list will be stored in session, until the button labeled Stop Conversation is clicked.

Note

During the conversation, the user may execute AJAX/non-AJAX requests against the bean or perform navigations to other pages that still reference this same managed bean. The bean will keep its state across user interactions using a conversation identifier generated by the container, and this is why the conversation scope can be the right choice when you need to implement wizards. But it might be a good idea to take into account the new JSF 2.2 flow scope as well, which solves several gaps of the conversation scope. See the upcoming section!

In this example, the conversation context automatically propagates with any JSF faces request or redirection (this facilitates the implementation of the common POST-then-redirect pattern), but it does not automatically propagate with non-faces requests, such as links. In this case, you need to include the unique identifier of the conversation as a request parameter. The CDI specification reserves the request parameter cid for this use. The following code will propagate the conversation context over a link:

<h:link outcome="/link.xhtml" value="Conversation Propagation">
  <f:param name="cid" value="#{conversation.id}"/>
</h:link>

Note

A method annotated with @PostConstruct will be called for each request as long as the bean is not involved in a conversation. When the conversation begins, the method is called for that instance and subsequent requests will use this instance until the conversation ends. Therefore, be careful how you manage this method content.

This example is wrapped into the application named ch3_4 and is available in the code bundle of this chapter.

主站蜘蛛池模板: 蒲城县| 金乡县| 贵阳市| 那坡县| 连云港市| 贵阳市| 常熟市| 南昌县| 梁山县| 五指山市| 富源县| 突泉县| 横山县| 陵川县| 双鸭山市| 商水县| 丹寨县| 西昌市| 马山县| 云浮市| 黄浦区| 河北区| 萝北县| 洮南市| 闽侯县| 定襄县| 蒙自县| 宝山区| 阜平县| 晴隆县| 建始县| 林口县| 三穗县| 连城县| 家居| 尉氏县| 兴义市| 靖宇县| 喜德县| 叶城县| 罗田县|