JSF 2.0: файлы cookie не сохраняются сразу после вызова AJAX, требуется HTTP-запрос - PullRequest
2 голосов
/ 19 января 2011

Ajax-вызов выполняется для удаления товара из корзины - removeOrder() вызывается метод

UI removeOrder() вызов (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>

Backend removeOrder() вызов(управляемый компонент)

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 действительно очищается.

Как я вижу, clash:
после того, как AJAX-вызов очищает cookie-файл, HttpServletRequest содержит непустой cookie-файл до тех пор, пока не будет выполнен новый HTTP-запрос (кнопка подтверждения пользователя или переход по ссылке).* Есть ли решение или хорошая практика для немедленного управления файлами cookie, когда веб-приложение объединяет вызовы AJAX и не AJAX?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 25 июня 2011

Ваша проблема с cookie - это одно, но я думаю, что есть гораздо более простой способ добиться цели.

На своей странице просто замените упомянутые вами страницы на:

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

Поддерживающий компонент (например, область действия сеанса):

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

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

Я предполагаю, что вы показываете промежуточный итог и, возможно, перечислите все продукты после вызова removeOrder .Просто пересчитайте промежуточный итог после удаления продукта и убедитесь, что корзина обновлена ​​(атрибут update ).

Этот код достаточно прост и понятен, но при этом выполняет все необходимое.Нет необходимости вручную управлять файлами cookie.

1 голос
/ 29 июня 2011

Подожди, что?В emptyCartNotifier Вы вызываете getCookies для объекта HttpRequest, который должен содержать файлы cookie, которые были в HTTP-запросе , которые вызвали ваш метод, поэтому, конечно, вы не видитеменяется до следующего запроса.

1 голос
/ 20 января 2011

Вы можете попробовать установить свои куки setHttpOnly(true), но вопрос в том, зачем вам вообще нужна сохранность файлов cookie в «ajax-scoped»?

Почему бы не использовать локальные переменные в ваших bean-компонентах вида / запроса / сеанса? Они на самом деле предназначены для такого рода задач. Если вам нужно дополнительное сохранение cookie, вы делаете это в соответствующих методах установки или действиях.

...