【问题标题】:HttpClient - Cookies - and JEditorPaneHttpClient - Cookies - 和 JEditorPane
【发布时间】:2011-08-13 03:59:28
【问题描述】:

我已经成功地使用 httpclient 登录到一个站点并打印出启用该登录的 cookie。 但是,我现在卡住了,因为我想使用 .setPage(url) 函数在 JEditorPane 中显示后续页面。但是,当我这样做并使用 Wireshark 分析我的 GET 请求时,我发现用户代理不是我的 httpclient,而是以下内容:

用户代理:Java/1.6.0_17

GET 请求(在 jeditorpane 的 setPage(URL url) 方法中的某处编码)没有使用 httpclient 检索的 cookie。我的问题是 - 我怎样才能以某种方式传输通过 httpclient 收到的 cookie,以便我的 JEditorPane 可以显示来自该站点的 URL? 我开始认为这是不可能的,我应该尝试使用普通的 Java URLconnection 等登录,但宁愿坚持使用 httpclient,因为它更灵活(我认为)。大概我的 cookie 还是有问题的??

我曾想过扩展 JEditorPane 类并覆盖 setPage(),但我不知道应该放入其中的实际代码,因为似乎无法了解 setPage() 的实际工作原理。

任何帮助/建议将不胜感激。

戴夫

【问题讨论】:

  • 您在这里遇到的问题是 HttpClient 和 JVM 在您调用 setPage() 时用来获取 URL 的底层实现是完全不同的动物。因此,cookie 不会神奇地保留下来。
  • @stevevls,我认为可能是这种情况。那么如果我使用 Urlconnection 路由,它们会自动结转吗?感谢您的帮助
  • 所以我想我已经弄清楚了如何做你想做的事。看看答案,如果它适合你,请接受它。祝你好运!

标签: java httpclient


【解决方案1】:

在 Java 5 和 6 下,有一个默认的 cookie 管理器“自动”支持 HttpURLConnection,即 JEditorPane 默认使用的连接类型。 基于this blog entry,如果你写类似

CookieManager manager = new CookieManager();
manager.setCookiePolicy(CookiePolicy.ACCEPT_NONE);
CookieHandler.setDefault(manager);

似乎足以支持 JEditorPane 中的 cookie。 确保在与 JEditorPane 进行任何 Internet 通信之前添加此代码。

【讨论】:

    【解决方案2】:

    正如我在评论中提到的,JEditorPane 用于获取 URL 内容的 HttpClient 和 URLConnection 不会相互通信。因此,HttpClient 可能获取的任何 cookie 都不会传输到 URLConnection。但是,您可以像这样子类化 JEditorPane:

    final HttpClient httpClient = new DefaultHttpClient();
    
    /* initialize httpClient and fetch your login page to get the cookies */
    
    JEditorPane myPane = new JEditorPane() {
        protected InputStream getStream(URL url) throws IOException {
    
            HttpGet httpget = new HttpGet(url.toExternalForm());
    
            HttpResponse response = httpClient.execute(httpget);
            HttpEntity entity = response.getEntity();
    
            // important!  by overriding getStream you're responsible for setting content type!
            setContentType(entity.getContentType().getValue());
    
            // another thing that you're now responsible for...  this will be used to resolve
            // the images and other relative references.  also beware whether it needs to be a url or string
            getDocument().putProperty(Document.StreamDescriptionProperty, url);
    
            // using commons-io here to take care of some of the more annoying aspects of InputStream
            InputStream content = entity.getContent();
            try {
                return new ByteArrayInputStream(IOUtils.toByteArray(content));
            }
            catch(RuntimeException e) {
                httpget.abort();  // per example in HttpClient, abort needs to be called on unexpected exceptions
                throw e;
            }
            finally {
                IOUtils.closeQuietly(content);
            }
        }
    };
    
    // now you can do this!
    myPane.setPage(new URL("http://www.google.com/"));
    

    通过进行此更改,您将使用 HttpClient 获取 JEditorPane 的 URL 内容。请务必阅读此处的 JavaDoc http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/JEditorPane.html#getStream(java.net.URL) 以确保您了解所有极端情况。我想我已经对其中的大部分进行了排序,但我不是专家。

    当然,您可以更改代码的 HttpClient 部分以避免先将响应加载到内存中,但这是最简洁的方式。而且由于您要将其加载到编辑器中,因此它会在某个时候全部存储在内存中。 ;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多