Can't set cookie on PostConstruct

I have this code to set a cookie during page load, however it doesn't work:

markup:

<ui:fragment rendered="#{surveyWebBean.showQuestions}">
    <ui:include src="/general/survey.xhtml" />
</ui:fragment>

      

code:

SurveyWebBean.java

@ManagedBean(name = "surveyWebBean")
@SessionScoped
public class EncuestasWebBean extends BaseBean {

    private boolean showQuestions;

    @PostConstruct
    public void init() {
        showQuestions = true;
        UUID uuid = UUID.randomUUID();
        CookieHelper ch = new CookieHelper();
        ch.setCookie("COOKIE_UUID_SURVEY", uuid.toString(), 60 * 60 * 24 * 365 * 10);
    }

    //Getters and Setters
}

      

CookieHelper.java

public class CookieHelper {

    public void setCookie(String name, String value, int expiry) {

        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
        Cookie cookie = null;
        Cookie[] userCookies = request.getCookies();

        if (userCookies != null && userCookies.length > 0) {
            for (int i = 0; i < userCookies.length; i++) {
                if (userCookies[i].getName().equals(name)) {
                    cookie = userCookies[i];
                    break;
                }
            }
        }

        if (cookie != null) {
            cookie.setValue(value);
        } else {
            cookie = new Cookie(name, value);
            cookie.setPath("/");
        }

        cookie.setMaxAge(expiry);
        HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
        response.addCookie(cookie);
    }

    public Cookie getCookie(String name) {

        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
        Cookie cookie = null;
        Cookie[] userCookies = request.getCookies();

        if (userCookies != null && userCookies.length > 0) {
            for (int i = 0; i < userCookies.length; i++) {
                if (userCookies[i].getName().equals(name)) {
                    cookie = userCookies[i];
                    return cookie;
                }
            }
        }
        return null;
    }
}

      

However, when I try to retrieve the cookie or inspect it in the Google Chrome inspector or local data viewer, it doesn't exit

Any idea?

+3


source to share


1 answer


It looks like the bean is referencing the response rendering for the first time. You cannot set cookies during the rendering response phase. Cookies are set in HTTP response headers. But at the moment JSF is busy generating some HTML output in the response body, the response headers are most likely already sent out for a long time.

You need to set a cookie before the first bit is written to the response body.

You can use the <f:event type="preRenderView">

bean to call the listener method right before the render response starts.

<f:event type="preRenderView" listener="#{surveyWebBean.init}" />

      

public void init() { // (remove @PostConstruct!)
    if (showQuestions) {
        return; // Already initialized during a previous request in same session.
    }

    showQuestions = true;
    UUID uuid = UUID.randomUUID();
    CookieHelper ch = new CookieHelper();
    ch.setCookie("COOKIE_UUID_SURVEY", uuid.toString(), 60 * 60 * 24 * 365 * 10);
}

      




Not tied to a specific issue like CookieHelper

you might have found them in a JSF 1.x based resource, but you need to know that since JSF 2.0 contains new cookie-related methods ExternalContext

for example getRequestCookieMap()

which should make it easier to get cookie. Faces

the JSF utility class OmniFaces librarty has some cookie-related methods as well.

Faces.addResponseCookie("cookieName", cookieValue, "/", 60 * 60 * 24 * 365 * 10);

      

String cookieValue = Faces.getRequestCookie("cookieName");

      

+3


source







All Articles