有没有办法在Java中从响应对象中读取cookie?

24

看起来HttpServletResponse没有暴露任何用于此操作的方法。

现在,我正在向一个混乱且不易理解的Servlet中添加大量日志代码,以尝试弄清楚它到底是做什么的。我知道它设置了一堆cookies,但我不知道什么时候、为什么或者是什么。在Servlet执行结束时记录HttpServletResponse对象中的所有cookie将是很好的。

我知道cookie通常是浏览器的职责,而且我记得在.NET中没有办法做到这一点。只是希望Java可能会有所不同......

但如果这不可能——有没有其他想法可以实现我的目标?

谢谢,一如既往。

4个回答

20

如果你只需要记录日志,那么我建议编写一个实现了javax.servlet.Filter接口的过滤器,该过滤器将提供的HttpServletResponse包装在一个包装器中,在过滤器执行后允许你公开 cookies。像这样:

public class CookieLoggingFilter implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException ,ServletException {
        ResponseWrapper wrappedResponse = new ResponseWrapper((HttpServletResponse) response);

        filterChain.doFilter(request, wrappedResponse);

        // use a real logger here, naturally :)
        System.out.println("Cookies: " + wrappedResponse.cookies); 
    }

    private class ResponseWrapper extends HttpServletResponseWrapper {

        private Collection<Cookie> cookies = new ArrayList<Cookie>();

        public ResponseWrapper(HttpServletResponse response) {
            super(response);
        }

        @Override
        public void addCookie(Cookie cookie) {
            super.addCookie(cookie);
            cookies.add(cookie);
        }
    }

       // other methods here
}

需要注意的是:这种方法无法显示响应返回到浏览器的 cookie,它只会展示应用程序代码添加到响应中的 cookie。如果容器选择更改、添加或忽略这些 cookie(例如会话 cookie 由容器处理而不是应用程序),则无法使用此方法了解。但对于您的情况可能并不重要。

唯一确定的方法是使用类似于 Firefox 的 Live Http Headers 浏览器插件,或者使用人中之龙的 HTTP 日志代理。


也许我漏掉了什么... 为什么不能扩展您容器的标准日志记录(例如Tomcat的AccessLogValve),并过滤响应头以查找要记录的Set-Cookie?这样应该可以记录在浏览器中设置的明确的cookie。 - Alex Dean

10

我遇到了同样的问题,我正在使用一个接受HttpServletResponse的第三方库,我需要读取它在我的响应对象上设置的cookie。为了解决这个问题,我创建了一个HttpServletResponseWrapper扩展,当我调用后,它为我暴露了这些cookie:

public class CookieAwareHttpServletResponse extends HttpServletResponseWrapper {

    private List<Cookie> cookies = new ArrayList<Cookie>();

    public CookieAwareHttpServletResponse (HttpServletResponse aResponse) {
        super (aResponse);
    }

    @Override
    public void addCookie (Cookie aCookie) {
        cookies.add (aCookie);
        super.addCookie(aCookie);
    }

    public List<Cookie> getCookies () {
        return Collections.unmodifiableList (cookies);
    }

} 

而我使用它的方式:

// wrap the response object
CookieAwareHttpServletResponse response = new CookieAwareHttpServletResponse(aResponse);

// make the call to the 3rd party library 
String order = orderService.getOrder (aRequest, response, String.class);

// get the list of cookies set
List<Cookie> cookies = response.getCookies();

5

您唯一的方法是包装HttpServletResponse对象,使addCookie方法可以拦截并记录设置cookie的情况。您可以通过添加一个ServletFilter来实现这一点,在将现有的HttpServletResponse传递到您的Servlet之前对其进行包装。


1

在“Set-Cookie”响应头中发送Cookie到客户端。尝试以下操作:

private static void logResponseHeaders(HttpServletResponse httpServletResponse) {

    Collection<String> headerNames = httpServletResponse.getHeaderNames();

    for (String headerName : headerNames) {
        if (headerName.equals("Set-Cookie")) {
            log.info("Response header name={}, header value={}", headerName, httpServletResponse.getHeader(headerName));
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接