Comment remplacer @ManagedBean / @ViewScope par CDI dans JSF 2.0 / 2.1
je suis en train d'évaluer Java EE 6 / JSF 2.1 avec RichFaces.
Un haricot qui est déclaré comme
@ManagedBean
@ViewScoped
- reçoit un jeu D'ID (pour préparer par exemple une opération de suppression).
- Via JSF un popup de confirmation s'affiche.
- si l'utilisateur confirme, la méthode de suppression est invoquée et supprime la ligne pour laquelle L'ID a été stocké à l'étape 1.
depuis le CDI les haricots n'ont pas de vue j'ai essayé de déclarer le haricot comme:
@Named
@ConversationScoped
Maintenant, le traitement échoue à l'étape 3. parce que la valeur qui a été définie lors de l'étape 1 (vérifié) n'est plus disponible.
dois-je utiliser les méthodes Conversation.begin()
et Conversation.end()
?
si oui, où serait-il bon de les invoquer?
5 réponses
si vous pouvez passer à JSF 2.2, faites-le immédiatement. Il offre une annotation @ViewScoped
pour le CDI.
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
alternativement, installer OmniFaces qui apporte son propre CDI compatible @ViewScoped
, y compris un @PreDestroy
de travail (qui est cassé sur JSF @ViewScoped
).
import javax.inject.Named;
import org.omnifaces.cdi.ViewScoped;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
une autre alternative est d'installer MyFaces CODI qui relie de manière transparente JSF 2.0/2.1 @ViewScoped
au CDI. Cela ajoute seulement un paramètre de requête autogénérée à L'URL (comme @ConversationScoped
le ferait).
import javax.faces.bean.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
si vous avez vraiment besoin d'utiliser @ConversationScoped
, alors vous devez effectivement commencer et finir maunalement. Vous devez @Inject
a Conversation
et invoquer begin()
dans le @PostConstruct
et end()
dans la dernière étape de la conversation, habituellement 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";
}
}
voir aussi:
je pense que vous pouvez bénéficier de L'extension du CDI pour créer votre propre portée afin que vous puissiez mettre en œuvre le contexte et utiliser le @NormalScope
.
- le CDI lance un événement
AfterBeanDiscovery
après chaque appel de haricots - vous pouvez utiliser L'extension CDI à
@Observes
cet événement et ajouter votre mise en œuvre de contexte - dans votre implémentation de scope vous pouvez :
- utilisez
Contextual
pour obtenir votre haricot par son nom deFacesContext
ViewRoot
Map
et le retourner après chaque appel ajax "
- utiliser
CreationalContext
si le nom du haricot de la première étape n'est pas trouvé pour le créer dans leFacesContext
ViewRoot
Map
- utilisez
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 /
injecte la conversation dans ton haricot et dans la méthode @PostConstructor
commence la conversation si la conversation est transitoire.
et après avoir supprimé l'enregistrement, mettez fin à votre conversation et naviguez jusqu'à votre page de destination. Lorsque l'on commence 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 y a un projet qui contient des extentions aux caractéristiques de la pile Java EE: DeltaSpike . C'est une consolidation de la couche 3, Apache CODI. Parmi les autres, il y a surtout le @ViewScoped dans le CDI. C'est un vieil article et maintenant il a atteint la version 1.3.0
vous pouvez utiliser:
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");
}
}