JSF 2.0: Las cookies no se persistió inmediatamente después de la llamada AJAX, HTTP solicitud según lo
-
12-10-2019 - |
Pregunta
Ajax llamada a cabo con el fin de elemento eliminar de carrito de la compra - removeOrder()
método se llama
interfaz de usuario llamada removeOrder()
(JSF y 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 llamada removeOrder()
(bean gestionado)
public void removeOrder(ActionEvent e) {
String productName = (String) e.getComponent().getAttributes().get("remove");
Product p = getProductByName(productName);
inCart.remove(p);
persistCookies();
emptyCartNotifier();
totalRendered();
}
A continuación, las cookies se conserva, la salida de este método como se espera, matriz cookie contiene galletas con valores vacíos, eso está bien:
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);
}
Aquí problema se produjo, la emptyCartNotifier método () ver no vacíos Cookies "anteriores" array
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;
}
Después de cualquier solicitud HTTP a cabo, esa matriz de cookies es realmente limpiado.
Tal como lo veo, choque es:.
después de AJAX limpia de llamada galleta, que contiene HttpServletRequest
cookies no vacío hasta que la nueva petición HTTP realizada (usuario botón de enviar o pasar enlace)
¿Hay solución o buenas prácticas para la gestión de cookies inmediata, cuando se combina web-app AJAX y no AJAX llamadas?
Gracias.
Solución
Wait, what? In emptyCartNotifier
, You are calling getCookies
on the HttpRequest
object, which is supposed to contain the cookies that were in the HTTP request that triggered your method, so of course you don't see changes until the next request.
Otros consejos
Your cookie problem is one thing, but I think there is a much easier way to get things done.
In your page, just replace the pages you mention with this:
<p:commandButton value="clean" action="#{showProducts.removeOrder(cart)}"
process="@form" update="@form,:ccId:cCart:ccSizeId,:ccId:cCart:ccTotId" immediate="true" />
Backing bean (e.g. session scoped):
private double subtotal; // don't forget getter and setter
public void removeOrder(Product product) {
inCart.remove(product);
// calculate subtotal
}
I guess you show the subtotal and maybe list all products after calling removeOrder. Just recalculate subtotal after removing the product, and make sure the shopping cart is refreshed (update attribute).
This code is simple enough and easy to understand, and yet does everything you need. No need to "manually" manage cookies.
You could try setting your cookies setHttpOnly(true)
, but the question is why would you need "ajax-scoped" cookie persistence at all?
Why not use local variables in your view/request/session scoped beans? They're actually designed for that sort of tasks. If you want additional cookie persistence you do it in corresponding setters or action methods.