web-dev-qa-db-ja.com

JSF 2.0 / 2.1で@ManagedBean / @ViewScopeをCDIに置き換える方法

現在、RichFacesでJava EE 6/JSF 2.1を評価しています。

として宣言されているBean

_@ManagedBean
@ViewScoped
_
  1. IDセットを取得します(削除操作などを準備するため)。
  2. JSFを介して確認ポップアップが表示されます。
  3. ユーザーが確認すると、deleteメソッドが呼び出され、ステップ1でIDが保存された行が削除されます。

CDI BeanにはViewScopeがないため、Beanを次のように宣言しようとしました。

_@Named
@ConversationScoped
_

ステップ1で設定された(チェックされた)値が使用できなくなったため、ステップ3で処理が失敗します。

Conversation.begin()およびConversation.end()メソッドを使用する必要がありますか?

もしそうなら、それらを呼び出すための良い場所はどこでしょうか?

24
stacker

JSF 2.2にアップグレードできる場合は、すぐに実行してください。 CDIにネイティブの _@ViewScoped_ アノテーションを提供します。

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

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

または、インストール OmniFaces 独自のCDI互換性 _@ViewScoped_ をインストールします。動作する_@PreDestroy_(JSF _@ViewScoped_で破損) 。

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

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

別の方法は、JSF 2.0/2.1 _@ViewScoped_を透過的にCDIにブリッジする MyFaces CODI をインストールすることです。これは、自動生成されたリクエストパラメータをURLに追加するだけです(_@ConversationScoped_のように)。

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

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

_@ConversationScoped_を本当に使用する必要がある場合は、実際にそれを手動で開始および終了する必要があります。 _@Inject_ a Conversation を実行し、_@PostConstruct_でbegin()を呼び出し、最後のステップでend()を呼び出す必要があります。会話、通常は新しいビューにリダイレクトするアクションメソッド。

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

}
_

以下も参照してください。

52
BalusC

CDI拡張機能を利用して独自のスコープを作成し、コンテキストを実装して@NormalScopeを使用できるようになると思います。

  • CDIは各Bean呼び出しの後にイベントAfterBeanDiscoveryを起動します
  • CDI拡張機能を使用してこのイベントを@Observesし、コンテキスト実装を追加できます
  • スコープの実装では、次のことができます。
    1. Contextualを使用して、FacesContextViewRootMapからBeanを名前で取得し、各ajaxコールバック後にそれを返します
    2. 最初のステップからのBean名が見つからない場合はCreationalContextを使用してFacesContextViewRootMapに作成します

より詳細な説明については、このリンクをお勧めします: http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/

6
Kurohige

会話をBeanに挿入し、一時的なものである場合は@PostConstructorメソッドで会話を開始します。

そして、レコードを削除した後、会話を終了し、宛先ページに移動します。会話を始めるとき。ここに例があります

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
cubbuk

Java EEスタック機能: DeltaSpike への拡張を保持するプロジェクトがあります。これはSeam 3、Apache CODIの統合です。他のものの上に、 @ViewScoped to CDI。これは古い記事であり、現在バージョン1.3.0に達しています。

0
Endrik