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

这里cookies是持久化的,这个方法的输出和预期的一样,cookie数组包含空值的cookies,没关系:

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() 看到非空的“previous” Cookies数组

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 之后,该 cookieHttpServletRequest包含非空 cookie,直到执行新的 HTTP 请求(用户提交按钮或通过链接访问)。

当网络应用程序结合 AJAX 和非 AJAX 调用时,是否有即时 cookie 管理的解决方案或良好做法?

谢谢你。

4

3 回答 3

2

您的 cookie 问题是一回事,但我认为有一种更简单的方法可以完成任务。

在您的页面中,只需将您提到的页面替换为:

<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

等等,什么?在emptyCartNotifier中,您正在调用getCookiesHttpRequest对象,该对象应该包含触发您的方法的 HTTP 请求中的 cookie ,因此当然在下一个请求之前您不会看到更改。

于 2011-06-29T10:53:30.250 回答
1

您可以尝试设置您的 cookies setHttpOnly(true),但问题是您为什么需要“ajax-scoped” cookie 持久性?

为什么不在视图/请求/会话范围的 bean 中使用局部变量?它们实际上是为这类任务而设计的。如果你想要额外的 cookie 持久性,你可以在相应的 setter 或 action 方法中进行。

于 2011-01-20T07:16:29.083 回答