使用过滤器将cookie添加到用户会话

时间:2011-10-21 04:58:25

标签: java cookies response servlet-filters

更新:问题在于MaxAge使用的设置。将其设置为零将导致cookie被删除,因此它显示在响应标头中,但随后被删除并且未在请求中显示。将其设置为-1,以便不会持久存储

我正在对过滤器做一些工作,我想让它设置一个cookie来表明用户有资格参加调查,并且下次他回到该网站时会显示一个调查弹出窗口。< / p>

我没有在日志中看到任何错误,但cookie永远不会被设置。

可以通过这种方式使用过滤器来添加Cookie吗?是否存在HttpServletResponseWrapper发挥作用的地方?

这里的想法是,当用户访问该站点时,检查是否存在cookie。如果不是,则创建cookie并将其添加到响应中。当用户导航网站时,将调用cookie检查方法以确保不会为该给定用户增加计数器。

cookie检查方法永远不会看到cookie。使用firefox的web开发人员插件,有问题的cookie不存在。

以下是带有相关方法的过滤器类。

public class HitCounterFilter extends TemplateFilter {
    public void doMainProcessing(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) {
        HttpServletRequest httpRequest = (HttpServletRequest) pRequest;
        HttpServletResponse httpResponse = (HttpServletResponse) pResponse;

        // prevent thread interference and memory consistency errors
        synchronized (lock) {
            int hitCounter = this.readFile(localFile);

            // if user has not been counted
            if (!this.checkForCookie(httpRequest, "gtgo_visitor")) {
                this.writeFile(localFile, ++hitCounter);
                this.createCookie(httpRequest, httpResponse, String.valueOf(hitCounter), "gtgo_visitor");
            }
        }
    }

    private void createCookie(HttpServletRequest pHttpRequest, HttpServletResponse pHttpResponse, String pCookieValue, String pCookieName) {
        try {
            Cookie cookie = new Cookie(pCookieName, pCookieValue);
            URL url = new URL(pHttpRequest.getRequestURL().toString());
            cookie.setDomain(url.getHost());
            cookie.setPath(this.getCookiePath(pHttpRequest));
            cookie.setComment("user is not eligible to take the survey this time");
            cookie.setMaxAge(0);

            pHttpResponse.addCookie(cookie);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    private boolean checkForCookie(HttpServletRequest pHttpRequest, String pCookieName) {
        for (Cookie cookie : pHttpRequest.getCookies()) {
            if (StringUtils.equalsIgnoreCase(cookie.getName(), pCookieName)) {
                return true;
            }
        }
        return false;
    }
} 

2 个答案:

答案 0 :(得分:1)

问题在于MaxAge使用的设置。将其设置为零将导致cookie被删除,因此它显示在响应标头中,但随后被删除并且未在请求中显示。将其设置为-1,以便不会持久存储 - 只要会话处于活动状态(会话关闭后删除),它就会出现。

答案 1 :(得分:0)

之前我没有使用SCAM项目,但看起来这就是你正在使用的。我不确定超类的doFilter实现是否在调用FilterChain的doFilter方法之前调用了实现的doMainProcessing方法。

因为框架将FilterChain传递给你的doMainProcessing方法,所以很可能它会期望你的实现调用pChain.doFilter(pRequest,pResponse,pChain)。

我可能错了,但如果放弃过滤器链,写入ServletResponse对象的标头(包括您附加的cookie)可能不会返回给客户端。

在任何情况下,除非您专门阻止对所请求资源的访问,否则使用FilterChain传播请求是明智的。