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
  1. reçoit un jeu D'ID (pour préparer par exemple une opération de suppression).
  2. Via JSF un popup de confirmation s'affiche.
  3. 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?

21
demandé sur BalusC 2013-01-17 21:10:07

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:

47
répondu BalusC 2017-05-23 11:47:13

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 :
    1. utilisez Contextual pour obtenir votre haricot par son nom de FacesContext ViewRoot Map et le retourner après chaque appel ajax
    2. "
    3. utiliser CreationalContext si le nom du haricot de la première étape n'est pas trouvé pour le créer dans le 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 /

6
répondu Kurohige 2014-11-06 05:06:52

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";
    }

}
3
répondu cubbuk 2013-01-17 17:39:39

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

0
répondu Endrik 2015-05-06 13:19:20

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");
    }

}
-1
répondu jclafuente 2015-04-18 13:01:43