Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

jsf 2 - How to replace @ManagedBean / @ViewScope by CDI in JSF 2.0/2.1

I'm currently evaluating Java EE 6 / JSF 2.1 with RichFaces.

A bean which is declared as

@ManagedBean
@ViewScoped
  1. Gets an ID set (to prepare e.g. a delete operation).
  2. Via JSF a confirmation popup is displayed.
  3. If the user confirms, the delete method is invoked and removes the row for which the ID was stored in step 1.

Since CDI beans don't have a ViewScope I tried to declare the bean as:

@Named
@ConversationScoped

Now the processing fails in step 3. because the value that was set in step 1 (checked that) is no longer available.

Do I have to use Conversation.begin() and Conversation.end() methods?

If so, where would be good place to invoke them?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you can upgrade to JSF 2.2, immediately do it. It offers a native @ViewScoped annotation for CDI.

import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class Bean implements Serializable {
    // ...
}

Alternatively, install OmniFaces which brings its own CDI compatible @ViewScoped, including a working @PreDestroy (which is broken on JSF @ViewScoped).

import javax.inject.Named;
import org.omnifaces.cdi.ViewScoped;

@Named
@ViewScoped
public class Bean implements Serializable {
    // ...
}

Another alternative is to install MyFaces CODI which transparently bridges JSF 2.0/2.1 @ViewScoped to CDI. This only adds an autogenerated request parameter to the URL (like @ConversationScoped would do).

import javax.faces.bean.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class Bean implements Serializable {
    // ...
}

If you really need to use @ConversationScoped, then you indeed need to manually begin and end it. You need to @Inject a Conversation and invoke begin() in the @PostConstruct and end() in the latest step of the conversation, usually an action method which redirects to a new view.

import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Named;

@Named
@ConversationScoped
public class Bean implements Serializable {

    @Inject
    private Conversation conversation;

    // ...

    @PostConstruct
    public void init() {
        conversation.begin();
    }

    public String submit() {
        // ...

        conversation.end();
        return "some.xhtml?faces-redirect=true";
    }

}

See also:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...