1

私は非常に奇妙な問題に直面しました。プロキシ サーバーをサポートするインターネットからデータをダウンロードするアプリケーションを作成する 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 デスクトップ アプリケーションの「about」アクション リスナーを次のように書き換えます。

@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 インスタンスを作成する直前にこのコード スニペットをアプリケーションのメイン メソッドに追加すると、前述の行が渡され、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/ または、trashgod が提案したように、SwingWorker をその +1 で動作させましょう

于 2011-06-25T08:03:21.287 に答える
1

org.jdesktop.application.SingleFrameApplicationを除外して置き換えることで問題を解決しましFrameViewJFrame。もちろん、 の利点は失わFrameViewれますが、必要なものはすべて拡張して実装できますJFrame

残念ながら、なぜHttpClientが機能しないのかを調べる十分な時間がないSingleFrameApplicationため、提案された解決策は受け入れられます。

これが他の誰かに役立つことを願っています。

そして、参加してくれたtrashgodとmKorbelに感謝します。君たちありがとう。両方+1。

于 2011-06-29T07:14:50.960 に答える