Apache的HttpClient在Swing应用程序中睡着了

时间:2011-06-24 19:49:02

标签: java apache swing httpclient jsr296

我面临着非常奇怪的问题。编写应用程序以从代理服务器支持从Internet下载一些数据我决定使用Apache的HttpClient库。 jar二进制文件已成功添加到NetBeans项目中,并且在一个简单的应用程序中执行了以下代码片段(也已成功执行):

DefaultHttpClient httpclient = new DefaultHttpClient();
String proxyHost = "192.168.4.10";
Integer proxyPort = 8080;

HttpHost targetHost = new HttpHost("noaasis.noaa.gov", 80, "http");
HttpGet httpget = new HttpGet("/ptbus/ptbus167");

try {

    HttpHost proxy = new HttpHost(proxyHost, proxyPort);
    httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

    System.out.println("executing request: " + httpget.getRequestLine());
    System.out.println("via proxy: " + proxy);
    System.out.println("to target: " + targetHost);

    HttpResponse response = httpclient.execute(targetHost, httpget);
    HttpEntity entity = response.getEntity();

    System.out.println("----------------------------------------");
    System.out.println(response.getStatusLine());
    Header[] headers = response.getAllHeaders();
    for (int i = 0; i<headers.length; i++) {
        System.out.println(headers[i]);
    }

    System.out.println("----------------------------------------");
    System.out.println(response.getStatusLine());
    if (entity != null) {
        System.out.println("Response content length: " + entity.getContentLength());
    }
    EntityUtils.consume(entity);

}
catch (IOException ex) {

}
finally {
    // When HttpClient instance is no longer needed,
    // shut down the connection manager to ensure
    // immediate deallocation of all system resources
    httpclient.getConnectionManager().shutdown();
}

但是当我尝试在Swing应用程序中执行相同的操作时,它不起作用。例如,重写默认的Netbeans桌面应用程序的“关于”动作侦听器,如下所示

@Action
public void showAboutBox() {

    new Thread(new Runnable() {

        public void run() {

            DefaultHttpClient httpclient = new DefaultHttpClient();

            ......
            ......
            ......

            finally {
                // When HttpClient instance is no longer needed,
                // shut down the connection manager to ensure
                // immediate deallocation of all system resources
                httpclient.getConnectionManager().shutdown();
            }

        }
    }).start();
}

导致应用程序的执行停止在

中的某个地方
HttpResponse response = httpclient.execute(targetHost, httpget);

最少,它永远不会回来......

有趣的是,如果我在创建任何Swing实例之前将此代码段放在应用程序的main方法中,则会传递提到的行并收到HTTP响应。并且调用showAboutBox()不再导致问题 - 我也收到HTTP响应。

我做错了什么,伙计们?有什么诀窍?我可以在Swing应用程序中使用Apache的库吗?我无法理解会发生什么,并且没有发现任何与网上花费时间相似的内容。

感谢您的关注。希望有任何帮助!

3 个答案:

答案 0 :(得分:2)

你阻止了event dispatch thread(EDT)。使用SwingWorker,如图here所示。

答案 1 :(得分:2)

只有评论,但它的长度超过了允许的字符数....

为了避免错误的指示,基于Swing的gui并不关心你运行任何BackGround任务,Swing是单线程的,所有输出到GUI必须在EDT上完成

1 /将输出包装到SwingUtilities.invokeLater()的GUI,创建自己的EDT,如果存在EDT,则将实际任务移到EDT的末尾

2 /使用javax.swing.Action

将输出包装到GUI

3 /或者像trashgod建议的那样让SwingWorker适用于那个+1

答案 2 :(得分:1)

我通过排除org.jdesktop.application.SingleFrameApplication并将FrameView替换为JFrame来解决了这个问题。当然,一个人失去了FrameView的优势,但所有必需的东西都可以延伸JFrame

不幸的是,我没有足够的时间来检查为什么HttpClient无法与SingleFrameApplication一起使用,所以提出的解决方案对我来说是可以接受的。

希望这会有所帮助。

感谢trashgod和mKorbel的参与。感谢你们。两者都是+1。