1

我遇到了非常奇怪的问题。编写一个应用程序来从 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 的库吗?我无法理解会发生什么,也没有发现任何与在网上花费数小时类似的东西。

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

4

3 回答 3

2

您正在阻止事件调度线程(EDT)。使用,SwingWorker如图所示

于 2011-06-24T19:59:20.137 回答
2

仅评论但其长度超过允许的字符数....

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

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

2/ 使用 javax.swing.Action 将输出包装到 GUI

3/ 或者如垃圾神所建议的那样,让 SwingWorker 为 +1 工作

于 2011-06-25T08:03:21.287 回答
1

我通过排除org.jdesktop.application.SingleFrameApplication和替换解决FrameView了这个问题JFrame。当然,一个人失去了优势,FrameView但所有需要的东西都可以通过扩展来实现JFrame

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

希望这对其他人有帮助。

感谢垃圾神和 mKorbel 的参与。谢谢你们。两者都+1。

于 2011-06-29T07:14:50.960 回答