I\'m currently evaluating Java EE 6 / JSF 2.1 with RichFaces.
A bean which is declared as
@ManagedBean
@ViewScoped
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 maunally 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";
}
}
There is a project which holds an extentions to the Java EE stack features: DeltaSpike. It is a consolidation of Seam 3, Apache CODI. Above others, it includes the @ViewScoped into CDI. This is an old article and by now it has reached version 1.3.0
Inject the conversation into your bean and in the @PostConstructor
method start the conversation if the conversation is transient.
And after deleting the record, end your conversation and navigate to your destination page. When beginning a conversation. Here is an example
public class BaseWebBean implements Serializable {
private final static Logger logger = LoggerFactory.getLogger(BaseWebBean.class);
@Inject
protected Conversation conversation;
@PostConstruct
protected void initBean(){
}
public void continueOrInitConversation() {
if (conversation.isTransient()) {
conversation.begin();
logger.trace("conversation with id {} has started by {}.", conversation.getId(), getClass().getName());
}
}
public void endConversationIfContinuing() {
if (!conversation.isTransient()) {
logger.trace("conversation with id {} has ended by {}.", conversation.getId(), getClass().getName());
conversation.end();
}
}
}
@ConversationScoped
@Named
public class yourBean extends BaseWebBean implements Serializable {
@PostConstruct
public void initBean() {
super.initBean();
continueOrInitConversation();
}
public String deleteRow(Row row)
{
/*delete your row here*/
endConversationIfContinuing();
return "yourDestinationPageAfter removal";
}
}
You can use:
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class PageController implements Serializable {
private String value;
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void execute() {
setValue("value");
}
@PostConstruct
public void init() {
System.out.println("postcontructor");
}
}
I think you can benefit from CDI extension to create your own scope so you can implement the context and use the @NormalScope
.
AfterBeanDiscovery
after each bean call@Observes
this event and add your context implementationContextual
to get your bean by its name from FacesContext
ViewRoot
Map
and return it after each ajax call backCreationalContext
if the bean name from first step is not found to create it in the FacesContext
ViewRoot
Map
For a more in-depth explanation, I recommend this link : http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/