这个问题与我最近发布的另一个问题有关:Understanding HttpServletRequest and cookies in JSF

为了在JSF中实现“记住我”登录,我使用cookie并在WebFilter中读取它。筛选器获取cookie并在SessionScoped ManagedBean中设置cookie值,但是由于某些原因,ManagedBean无法在网页中显示它。

过滤器的doFilter实现:

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain)
        throws IOException, ServletException {

    HttpServletRequest req = (HttpServletRequest) request;
    Cookie[] cookies = req.getCookies();
    if (cookies != null) {
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("MyTestCookie")) {
                System.out.println("Filter got cookie: " + cookie.getValue());
                cookieBean.setValue(cookie.getValue());
            }
        }
    }
    chain.doFilter(request, response);
}


CookieBean类:

@ManagedBean
@SessionScoped
public class CookieBean implements Serializable {

    private String value;

    @PostConstruct
    public void init() {
        System.out.println("Instantiated CookieBean");
    }

    public String getValue() {
        System.out.println("CookieBean returning Value: " + value);
        return value;
    }

    public void setValue(String value) {
        System.out.println("CookieBean getting Value: " + value);
        this.value = value;
    }

    public void create() {
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        Map<String, Object> props = new HashMap<String, Object>();
        props.put("maxAge", 10000);
        ec.addResponseCookie("MyTestCookie", "Hello Cookie", props);
    }
}


CookieBean cookieBean通过javax.inject.Inject注释注入到过滤器中。

index.xhtml的正文:

<h:form>
    <h:commandButton value="Create Cookie!" action="#{cookieBean.create()}" >
        <f:ajax render="@form" />
    </h:commandButton>
    <p></p>
    <h:outputText value="Cookie value: #{cookieBean.value}" />
</h:form>


第一个问题是,设置cookie后,如果我启动新会话(通过打开新的浏览器会话),则网页无法识别cookie值,因为SessionScoped ManagedBean是在显示页面。

问题1:如何及时检测Cookie值以更新网页中的某些rendered属性?

第二个问题是,如果我通过按浏览器中的重新加载(或刷新)按钮来重新加载网页,则ManagedBean实例与以前相同(未触发@PostConstruct方法),但是该网页显示了一个空的cookie值,并且在服务器的输出中显示相同的值:

CookieBean returning Value: null
Filter got cookie: Hello Cookie
CookieBean getting Value: Hello Cookie


问题2:SessionScoped ManagedBean怎么可能丢失其属性而不重新创建?

最佳答案

问题1的答案:正如对此question的公认答案所解释的,我只需要在备用bean中进行重定向。这迫使JSF生成一个新的带有cookie的GET请求。假设请求页面是我的欢迎页面,那么我必须在cookieBean中编写它:

FacesContext.getCurrentInstance().getExternalContext().redirect("faces/index.xhtml");


好吧,这很好用,但是完整的URL现在显示在地址栏中。我将进一步调查是否有避免这种情况的方法。

对问题2的回答:SessionScoped cookieBean有效地实例化了两次,一次在部署过程中,另一次由过滤器实例化。问题是我正在使用JSF ManagedBean并将其注入javax.inject.Inject注释。我已经通过javax.inject.Namedjavax.enterprise.context.SessionScoped批注使其成为CDI Bean,并且注入现在工作良好。

关于java - WebFilter,EL和SessionScoped ManagedBean处理“记住我”登录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11637615/

10-11 06:38