简体   繁体   English

HttpClient-Cookies-和JEditorPane

[英]HttpClient - Cookies - and JEditorPane

I've successfully managed to logon to a site using httpclient and print out the cookies that enable that logon. 我已成功使用httpclient成功登录到站点,并打印出启用该登录的cookie。 However, I am now stuck because I wanted to display subsequent pages in a JEditorPane using .setPage(url) function. 但是,我现在陷入困境,因为我想使用.setPage(url)函数在JEditorPane中显示后续页面。 However, when I do that and analyse my GET request using Wireshark I see that the user agent is not my httpclient but the following: 但是,当我这样做并使用Wireshark分析我的GET请求时,我看到用户代理不是我的httpclient而是以下内容:

User-Agent: Java/1.6.0_17 用户代理:Java / 1.6.0_17

The GET request (which is coded somewhere in side jeditorpane's setPage(URL url) method) does not have the cookies that were retrieved using the httpclient. GET请求(在侧面jeditorpane的setPage(URL url)方法中编码)没有使用httpclient检索到的cookie。 My question is - how can I somehow transfer the cookies received with httpclient so that my JEditorPane can display URLs from the site? 我的问题是-如何以某种方式转移通过httpclient收到的cookie,以便我的JEditorPane可以显示该站点的URL? I'm beginning to think it's not possible and I should try and logon using normal Java URLconnection etc but would rather stick with httpclient as it's more flexible (I think). 我开始认为这是不可能的,我应该尝试使用普通的Java URLconnection等进行登录,但宁愿坚持使用httpclient,因为它更加灵活(我认为)。 Presumably I would still have a problem with the cookies?? 大概我还是对饼干有问题??

I had thought of extending the JEditorPane class and overriding the setPage() but I don't know the actual code I should put in it as can't seem to find out how setPage() actually works. 我曾考虑过扩展JEditorPane类并覆盖setPage(),但是我不知道应该输入的实际代码,因为似乎无法找出setPage()的实际工作方式。

Any help/suggestions would be greatly appreciated. 任何帮助/建议将不胜感激。

Dave 戴夫

As I mentioned in the comment, HttpClient and the URLConnection used by the JEditorPane to fetch the URL content don't talk to each other. 正如我在评论中提到的那样,HttpClient和JEditorPane用于获取URL内容的URLConnection彼此不对话。 So, any cookies that HttpClient may have fetched won't transfer over to the URLConnection. 因此,HttpClient可能已获取的任何cookie都不会转移到URLConnection。 However, you can subclass JEditorPane like so : 但是,您可以像这样子类化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/"));

By making this change, you'll be using HttpClient to fetch the URL content for your JEditorPane. 通过进行此更改,您将使用HttpClient来获取JEditorPane的URL内容。 Be sure to read the JavaDoc here http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/JEditorPane.html#getStream(java.net.URL ) to make sure that you catch all the corner cases. 请确保在此处http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/JEditorPane.html#getStream(java.net.URL )阅读JavaDoc,以确保您捕获了所有JavaDoc角落里的情况。 I think I've got most of them sorted, but I'm not an expert. 我想我大多数人都已排序,但我不是专家。

Of course, you can change around the HttpClient part of the code to avoid loading the response into memory first, but this is the most concise way. 当然,您可以在代码的HttpClient部分周围进行更改,以避免首先将响应加载到内存中,但这是最简洁的方法。 And since you're going to be loading it up into an editor, it will all be in memory at some point. 而且由于您要将其加载到编辑器中,因此某些时候它们都将在内存中。 ;) ;)

Under Java 5 & 6, there is a default cookie manager which "automatically" supports HttpURLConnection, the type of connection JEditorPane uses by default. 在Java 5和6下,有一个默认的cookie管理器,它“自动”支持HttpURLConnection,这是JEditorPane默认使用的连接类型。 Based on this blog entry , if you write something like 根据此博客条目 ,如果您编写类似

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

seems enough to support cookies in JEditorPane. 似乎足以在JEditorPane中支持cookie。 Make sure to add this code before any internet communication with JEditorPane takes place. 与JEditorPane进行任何Internet通信之前,请确保添加此代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM