Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
262 views
in Technique[技术] by (71.8m points)

java - HttpClient - Cookies - and JEditorPane

I've successfully managed to logon to a site using httpclient and print out the cookies that enable that logon. However, I am now stuck because I wanted to display subsequent pages in a JEditorPane using .setPage(url) function. 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:

User-Agent: 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. My question is - how can I somehow transfer the cookies received with httpclient so that my JEditorPane can display URLs from the site? 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). 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.

Any help/suggestions would be greatly appreciated.

Dave

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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. So, any cookies that HttpClient may have fetched won't transfer over to the URLConnection. However, you can subclass JEditorPane like so :

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. 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. 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. And since you're going to be loading it up into an editor, it will all be in memory at some point. ;)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...