HttpClient Apache засыпает в приложении Swing
Я столкнулся с очень странной проблемой. Написание приложения для загрузки некоторых данных из Интернета с поддержкой прокси-сервера я решил использовать библиотеку 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, это не работает. Например, переписав прослушиватель действий about по умолчанию для настольного приложения 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, упомянутая строка будет пропущена и получен ответ HTTP. И вызов showAboutBox() больше не вызывает проблемы - я тоже получаю ответ HTTP.
Что я делаю не так, ребята? В чем подвох? Могу ли я использовать библиотеку Apache в своем приложении Swing? Я не могу понять, что происходит, и не нашел ничего похожего на эти часы в сети.
Спасибо за внимание. Надеюсь на любую помощь!
3 ответа
Я решил проблему, исключив org.jdesktop.application.SingleFrameApplication
и замена FrameView
от JFrame
, Конечно, теряются преимущества FrameView
но все необходимые вещи могут быть реализованы, расширяя JFrame
,
К сожалению, у меня нет достаточно времени, чтобы выяснить, почему HttpClient
не работает с SingleFrameApplication
поэтому предложенное решение для меня приемлемо.
Надеюсь, это поможет кому-то еще.
И спасибо trashgod и mKorbel за участие. Спасибо вам, ребята. Оба +1.
Это только комментарии, но это больше, чем разрешено количество символов....
Чтобы избежать неправильных указаний, графический интерфейс на основе Swing не заботится о том, что вы выполняете какую-либо задачу BackGround, Swing является однопоточным, и весь вывод в графический интерфейс должен выполняться на EDT.
1/ перенесите вывод в графический интерфейс в SwingUtilities.invokeLater(), который создал ваш собственный EDT, и, если существует EDT, переместите текущую задачу в конец EDT
2 / обернуть вывод в графический интерфейс с помощью javax.swing.Action
3 / или, как предложил trashgod, давайте SwingWorker работает для этого +1
Вы блокируете поток рассылки событий (EDT). использование SwingWorker
, как показано здесь.