3

次の XHTML があります。

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <head>
        <title>TODO supply a title</title>
    </head>
    <body>
        <f:metadata>
            <f:viewParam id="productCV" name="productName" value="#{productBean.product}"
                         converter="#{productConverter}" required="true"/>
        </f:metadata>

        <ui:composition template="/templates/mastertemplate.xhtml">
            <!-- Define the page title for this page-->
            <ui:define name="pageTitle">
                <h:outputFormat value="#{msgs.productPageTitle}">
                    <f:param value="#{productBean.product.description}"/>
                </h:outputFormat>
            </ui:define>

            <!-- Pass the categoryName parameter to the sidebar so the category of this product is highlighted-->
            <ui:param name="categoryName" value="#{productBean.product.categoryName}"/>

            <ui:define name="content">
                <!-- If productconversion failed, show this error-->
                <h:message id="error" for="productCV" style="color: #0081c2;" rendered="#{productBean.product == null}" />

                <!-- If productconversion succeeded show the product page-->
                <h:panelGroup rendered="#{productBean.product != null}">
                    <p>#{productBean.product.description} #{productBean.product.categoryName}</p>
                    <h:form>
                        <h:commandLink action="#{cartBean.addItemToCart(productBean.product)}">
                            <f:ajax event="action" render=":cart :cartPrice" />
                            <h:graphicImage value="resources/img/addToCart.gif"/>
                        </h:commandLink>
                    </h:form>
                </h:panelGroup>
            </ui:define>
        </ui:composition>
    </body>
</html>

上部で、文字列を GET パラメータとして受け入れ、コンバーターを介して実行し、Productオブジェクトを取得します。これを に配置します。その Bean には、属性productBean.productのセッターとゲッターがあります。それだけです。Product

次に、このオブジェクトを使用して情報などを表示します。これは正常に機能します。また、commandLinkAJAX を使用してカートに追加します。私ProductBeanが にRequestScopeある場合、これは機能しません。それを入れるとSessionScope機能しますが、製品は 1 回しか追加されません。

これは簡単なことだと私は知ってRequestScopeいますが、なぜそれが で機能するのかわかりませんSessionScope

この投稿を読みましたが、これらの規則に違反しているとは思いません。

完全を期すために、これは私のものProductBeanです:

import be.kdg.shop.model.stock.Product;
import java.util.logging.Logger;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class ProductBean {

    private static final Logger logger = Logger.getLogger(ProductBean.class.getName());
    private Product product;

    public ProductBean() {}

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }
}
4

1 に答える 1

9

あなたのBeanはリクエストスコープです。したがって、Bean インスタンスは、単一の HTTP 要求応答サイクルの間存続します。

フォームを含むページが初めてリクエストされると、具体的なproductプロパティをビュー パラメータとして受け取る新しい Bean インスタンスが作成されます。関連付けられた応答を生成して送信した後、Bean インスタンスはガベージされます。これは、要求の終わりであるためです。

フォームが送信されると、事実上新しい HTTP リクエストが起動され、プロパティを含むすべてのプロパティがデフォルトに設定された新しい Bean インスタンスが作成されますproduct。この方法#{productBean.product}null、リクエスト全体に適用されます。renderedコマンド リンクの親コンポーネントの属性が評価されfalseます。したがって、コマンド リンク アクションはデコードされません。これは、 commandButton/commandLink/ajax アクション/リスナー メソッドが呼び出されていないか、入力値が更新されていないのポイント 5 に一致します。

解決策は、Bean をビュー スコープに配置することです。ビュー スコープ Bean は、同じ JSF ビューと対話 (送信/ポストバック) している限り存続します。標準の JSF はこれを提供@ViewScopedします。JSF の代わりに CDI を使用して Bean を管理しているため、最善の策は CDI@ConversationScopedです。これは比較的扱いにくい (自分でスコープを開始および終了する必要がある) ため、MyFaces CODIなどの CDI 拡張機能を提供する@ViewAccessScoped方が便利な場合があります。

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

于 2012-12-29T03:25:56.527 に答える