【问题标题】:Is there any way to read cookies from the response object in Java?有没有办法从 Java 中的响应对象中读取 cookie?
【发布时间】:2011-03-31 06:22:21
【问题描述】:

HttpServletResponse 似乎没有公开任何方法来做到这一点。

现在,我正在将一堆日志记录代码添加到一个笨拙且难以理解的 servlet 中,以试图弄清楚它究竟做了什么。我知道它设置了一堆 cookie,但我不知道何时、为什么或什么。最好在 servlet 执行结束时将所有 cookie 记录在 HttpServletResponse 对象中。

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

但如果这是不可能的 - 关于如何完成我正在尝试做的任何其他想法?

谢谢,一如既往。

【问题讨论】:

    标签: java cookies response servlets


    【解决方案1】:

    如果您只需要日志记录,那么我建议编写javax.servlet.Filter 的实现,它将提供的HttpServletResponse 包装在一个包装器中,这样您就可以在过滤器执行后公开cookie。像这样的:

    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 由容器而不是应用程序处理),您将不会知道使用这种方法。但这对您的情况可能无关紧要。

    唯一确定的方法是使用浏览器插件,如 Live Http Headers for Firefox,或中间人 HTTP 日志记录代理。

    【讨论】:

    • 也许我遗漏了一些东西...为什么不能扩展容器的标准日志记录(例如 Tomcat 的AccessLogValve)并过滤寻找Set-Cookies 记录的响应标头?这应该让您记录在浏览器中设置的最终 cookie。
    【解决方案2】:

    我在使用接受 HttpServletResponse 的 3rd 方库时遇到了同样的问题,我需要读回它在我的响应对象上设置的 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();
    

    【讨论】:

      【解决方案3】:

      您唯一的方法是包装 HttpServletResponse 对象,以便 addCookie 方法可以在设置 cookie 时拦截和记录。您可以通过添加一个 ServletFilter 来做到这一点,该过滤器在将现有 HttpServletResponse 传递到您的 Servlet 之前对其进行包装。

      【讨论】:

        【解决方案4】:

        Cookie 在“Set-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));
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-30
          • 1970-01-01
          • 2017-10-23
          • 1970-01-01
          相关资源
          最近更新 更多