2

ショッピングカートからアイテムを削除するために実行されるAjax呼び出し-removeOrder()メソッドが呼び出されます

UIremoveOrder()呼び出し(JSF&Primefaces):

<p:commandButton value="clean" actionListener="#{showProducts.removeOrder}"
   process="@form" update="@form,:ccId:cCart:ccSizeId,:ccId:cCart:ccTotId" immediate="true">
<f:attribute name="remove" value="#{cart.name}"/>
</p:commandButton>

バックエンドremoveOrder()呼び出し(マネージドBean)

public void removeOrder(ActionEvent e) {
        String productName = (String) e.getComponent().getAttributes().get("remove");
        Product p = getProductByName(productName);
        inCart.remove(p);
        persistCookies();
        emptyCartNotifier();
        totalRendered();
    }

ここでCookieは永続化され、期待どおりにこのメソッドが出力されます。Cookie配列には、値が空のCookieが含まれています。これで問題ありません。

private void persistCookies() {
    HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();

    String ids = "";

    for (Product prod : inCart) {
        // TODO change logic to support real count,for now 1 is available only
        ids += prod.getId() + ";" + prod.getCount() + "_";
    }

    Cookie cookie = new Cookie(SC_COOKIE, ids);
    Cookie cookie2 = new Cookie(SC_SIZE, String.valueOf(inCart.size()));
    Cookie cookie3 = new Cookie(SC_TOTAL_PRICE, String.valueOf(subTotal));
    cookie3.setPath("/");
    cookie3.setMaxAge(TWO_WEEKS);
    httpServletResponse.addCookie(cookie3);
    cookie.setPath("/");
    cookie.setMaxAge(TWO_WEEKS);
    cookie2.setPath("/");
    cookie2.setMaxAge(TWO_WEEKS);

    httpServletResponse.addCookie(cookie);
    httpServletResponse.addCookie(cookie2);

}

ここで問題が発生しました。メソッドemptyCartNotifier()は、空でない「前の」Cookie配列を参照します。

private String emptyCartNotifier() {

    HttpServletRequest httpServletRequest = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
    Cookie[] cookies = httpServletRequest.getCookies();
    boolean isCookiePresent = false;
    if (cookies != null) {
        for (Cookie c : cookies) {
            if (SC_COOKIE.equals(c.getName()) && (!c.getValue().isEmpty())) {
                isCookiePresent = true;
            }
        }
    }
    if (inCart.isEmpty() && (!isCookiePresent)) {
        emptyCartNotifier = "you cart is empty";
        isFormRendered = false;
    } else {
        emptyCartNotifier = "";
        isFormRendered = true;
    }
    return emptyCartNotifier;
}

HTTPリクエストが実行された後、そのCookie配列は実際にクリーンアップされます。

私が見るように、衝突は次のとおりです
。AJAX呼び出しがCookieをクリーンアップした後、HttpServletRequest新しいHTTPリクエストが実行されるまで(ユーザーの送信ボタンまたはリンクで移動)、空でないCookieが含まれます。

WebアプリがAJAX呼び出しと非AJAX呼び出しを組み合わせた場合、即時のCookie管理のための解決策またはグッドプラクティスはありますか?

ありがとうございました。

4

3 に答える 3

2

あなたのクッキーの問題は一つのことですが、私は物事を成し遂げるためのはるかに簡単な方法があると思います。

あなたのページで、あなたが言及したページをこれに置き換えるだけです:

<p:commandButton value="clean" action="#{showProducts.removeOrder(cart)}"
   process="@form" update="@form,:ccId:cCart:ccSizeId,:ccId:cCart:ccTotId" immediate="true" />

バッキングBean(例:セッションスコープ):

private double subtotal; // don't forget getter and setter

public void removeOrder(Product product) {
        inCart.remove(product);
        // calculate subtotal
}

removeOrderを呼び出した後、小計を表示し、すべての商品を一覧表示すると思います。商品を削除した後、小計を再計算し、ショッピングカートが更新されていることを確認してください(属性の更新)。

このコードは十分に単純で理解しやすいですが、それでも必要なすべてを実行します。Cookieを「手動で」管理する必要はありません。

于 2011-06-25T14:04:55.987 に答える
1

待って、何?で、メソッドをトリガーしたHTTPリクエストに含まれているはずのオブジェクトemptyCartNotifierを呼び出しgetCookiesているので、もちろん次のリクエストまで変更は表示されません。HttpRequest

于 2011-06-29T10:53:30.250 に答える
1

Cookieを設定してみることができますsetHttpOnly(true)が、問題は、なぜ「ajaxスコープ」のCookieの永続性が必要なのかということです。

ビュー/リクエスト/セッションスコープのBeanでローカル変数を使用してみませんか?それらは実際にはその種のタスクのために設計されています。追加のCookieの永続性が必要な場合は、対応するセッターまたはアクションメソッドで行います。

于 2011-01-20T07:16:29.083 に答える