J'évalue actuellement Java EE 6/JSF 2.1 avec RichFaces.
Un haricot qui est déclaré comme
@ManagedBean
@ViewScoped
Comme les beans CDI n’ont pas de ViewScope, j’ai essayé de déclarer le bean comme suit:
@Named
@ConversationScoped
À présent, le traitement échoue à l'étape 3. En effet, la valeur définie à l'étape 1 (cochée) n'est plus disponible.
Dois-je utiliser les méthodes Conversation.begin()
et Conversation.end()
?
Si oui, où serait le bon endroit pour les invoquer?
Si vous pouvez passer à JSF 2.2, faites-le immédiatement. Il offre une annotation @ViewScoped
native pour CDI.
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
Vous pouvez également installer OmniFaces qui apporte son propre CDI compatible @ViewScoped
, y compris un @PreDestroy
qui fonctionne (qui est interrompu sur JSF @ViewScoped
).
import javax.inject.Named;
import org.omnifaces.cdi.ViewScoped;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
Une autre solution consiste à installer MyFaces CODI qui relie de manière transparente JSF 2.0/2.1 @ViewScoped
à CDI. Cela ajoute uniquement un paramètre de requête généré automatiquement à l'URL (comme le ferait @ConversationScoped
).
import javax.faces.bean.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
Si vous devez vraiment utiliser @ConversationScoped
, alors vous devez commencer et terminer manuellement. Vous devez @Inject
a Conversation
et appeler begin()
dans les @PostConstruct
et end()
dans la dernière étape de la conversation, généralement une méthode d'action qui redirige vers une nouvelle vue.
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";
}
}
Je pense que vous pouvez bénéficier de l'extension CDI pour créer votre propre étendue afin de pouvoir implémenter le contexte et utiliser le @NormalScope
.
AfterBeanDiscovery
après chaque appel de haricot@Observes
cet événement et ajouter votre implémentation de contexteContextual
pour obtenir le nom de votre haricot parmi FacesContext
ViewRoot
Map
et le renvoyer après chaque rappel ajax.CreationalContext
si le nom du bean de la première étape n’est pas trouvé pour le créer dans la FacesContext
ViewRoot
Map
Pour une explication plus détaillée, je recommande ce lien: http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/
Injectez la conversation dans votre bean et utilisez la méthode @PostConstructor
pour démarrer la conversation si la conversation est transitoire.
Et après la suppression de l'enregistrement, mettez fin à la conversation et accédez à la page de destination. Au début d'une conversation. Voici un exemple
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";
}
}
Il existe un projet qui étend les fonctionnalités de la pile Java EE: DeltaSpike . C'est une consolidation de Seam 3, Apache CODI. Au-dessus des autres, il inclut le @ViewScoped dans CDI. Ceci est un ancien article qui a atteint la version 1.3.0.