Если вы обновили свой код HTTP-клиента Apache для использования новейшей библиотеки (на момент написания этой статьи это версия 4.3.5 для httpclient и версия 4.3.2 для httpcore) с версии 4.2.x, вы заметите, что некоторые классы, такие как org.apache.http.impl.client.DefaultHttpClient
или org.apache.http.params.HttpParams
, устарели. Ну, я был там, поэтому в этом посте я расскажу, как избавиться от предупреждений с помощью новых классов.
1. Вариант использования с Podcastpedia.org
Вариант использования, который я буду использовать для демонстрации, прост: у меня есть пакетное задание, чтобы проверить, есть ли новые эпизоды, доступные для подкастов. Чтобы избежать необходимости получать и анализировать ленту eTag
если новых эпизодов нет, я проверяю ранее, eTag
ли eTag
или last-modified
заголовки ресурса ленты с момента последнего вызова. Это будет работать, если издатель каналов поддерживает эти заголовки, что я настоятельно рекомендую, так как оно экономит полосу пропускания и вычислительную мощность для потребителей.
Так как это работает? Первоначально, когда новый подкаст добавляется в каталог Podcastpedia.org, я проверяю, присутствуют ли заголовки для ресурса канала, и если да, то я сохраняю их в базе данных. Для этого я выполняю HTTP-запрос HEAD к URL-адресу канала с помощью Apache Http Client. Согласно протоколу передачи гипертекста — HTTP / 1.1 rfc2616 , метаинформация, содержащаяся в заголовках HTTP в ответ на запрос HEAD, ДОЛЖНА быть идентична информации, отправленной в ответ на запрос GET).
В следующих разделах я представлю, как на самом деле выглядит код в Java до и после обновления до версии 4.3.x Apache Http Client.
2. Переход на версию 4.3.x
2.1. Программные зависимости
Для создания своего проекта, который, кстати, теперь доступен на GitHub — Podcastpedia-batch , я использую maven, поэтому я перечислил ниже зависимости, необходимые для Apache Http Client:
2.1.1. Перед
Apache Http Клиентские зависимости 4.2.x
01
02
03
04
05
06
07
08
09
10
11
|
<!-- Apache Http client --> < dependency > < groupId >org.apache.httpcomponents</ groupId > < artifactId >httpclient</ artifactId > < version >4.2.5</ version > </ dependency > < dependency > < groupId >org.apache.httpcomponents</ groupId > < artifactId >httpcore</ artifactId > < version >4.2.4</ version > </ dependency > |
2.1.2. После
Apache Http Client зависимости
01
02
03
04
05
06
07
08
09
10
11
|
<!-- Apache Http client --> < dependency > < groupId >org.apache.httpcomponents</ groupId > < artifactId >httpclient</ artifactId > < version >4.3.5</ version > </ dependency > < dependency > < groupId >org.apache.httpcomponents</ groupId > < artifactId >httpcore</ artifactId > < version >4.3.2</ version > </ dependency > |
2.2. HEAD-запрос с Apache Http Client
2.2.1. До v4.2.x
Пример выполнения запроса HEAD с помощью Apache HttpClient
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
private void setHeaderFieldAttributes(Podcast podcast) throws ClientProtocolException, IOException, DateParseException{ HttpHead headMethod = null ; headMethod = new HttpHead(podcast.getUrl()); org.apache.http.client.HttpClient httpClient = new DefaultHttpClient(poolingClientConnectionManager); HttpParams params = httpClient.getParams(); org.apache.http.params.HttpConnectionParams.setConnectionTimeout(params, 10000 ); org.apache.http.params.HttpConnectionParams.setSoTimeout(params, 10000 ); HttpResponse httpResponse = httpClient.execute(headMethod); int statusCode = httpResponse.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { LOG.error( "The introduced URL is not valid " + podcast.getUrl() + " : " + statusCode); } //set the new etag if existent org.apache.http.Header eTagHeader = httpResponse.getLastHeader( "etag" ); if (eTagHeader != null ){ podcast.setEtagHeaderField(eTagHeader.getValue()); } //set the new "last modified" header field if existent org.apache.http.Header lastModifiedHeader= httpResponse.getLastHeader( "last-modified" ); if (lastModifiedHeader != null ) { podcast.setLastModifiedHeaderField(DateUtil.parseDate(lastModifiedHeader.getValue())); podcast.setLastModifiedHeaderFieldStr(lastModifiedHeader.getValue()); } // Release the connection. headMethod.releaseConnection(); } |
Если вы используете интеллектуальную среду IDE, она сообщит вам, что DefaultHttpClient
, HttpParams
и HttpConnectionParams
устарели. Если вы посмотрите сейчас в их документах java, вы получите предложение об их замене, а именно, вместо этого использовать HttpClientBuilder
и классы, предоставляемые org.apache.http.config
.
Итак, как вы увидите в следующем разделе, именно это я и сделал.
2.2.2. После v 4.3.x
Пример запроса HEAD с Apache Http Client v 4.3.x
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
private void setHeaderFieldAttributes(Podcast podcast) throws ClientProtocolException, IOException, DateParseException{ HttpHead headMethod = null ; headMethod = new HttpHead(podcast.getUrl()); RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(TIMEOUT * 1000 ) .setConnectTimeout(TIMEOUT * 1000 ) .build(); CloseableHttpClient httpClient = HttpClientBuilder .create() .setDefaultRequestConfig(requestConfig) .setConnectionManager(poolingHttpClientConnectionManager) .build(); HttpResponse httpResponse = httpClient.execute(headMethod); int statusCode = httpResponse.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { LOG.error( "The introduced URL is not valid " + podcast.getUrl() + " : " + statusCode); } //set the new etag if existent Header eTagHeader = httpResponse.getLastHeader( "etag" ); if (eTagHeader != null ){ podcast.setEtagHeaderField(eTagHeader.getValue()); } //set the new "last modified" header field if existent Header lastModifiedHeader= httpResponse.getLastHeader( "last-modified" ); if (lastModifiedHeader != null ) { podcast.setLastModifiedHeaderField(DateUtil.parseDate(lastModifiedHeader.getValue())); podcast.setLastModifiedHeaderFieldStr(lastModifiedHeader.getValue()); } // Release the connection. headMethod.releaseConnection(); } |
Примечание:
- как
HttpClientBuilder
использовался для созданияClosableHttpClient
[строки 11-15], который является базовой реализациейHttpClient
который также реализуетCloseable
-
HttpParams
из предыдущей версии были заменены наorg.apache.http.client.config.RequestConfig
[строки 6-9], где я могу установить время ожидания сокета и соединения. Эта конфигурация позже используется (строка 13) при сборкеHttpClient
Оставшаяся часть кода довольно проста:
- запрос HEAD выполняется (строка 17)
- если он существует, то
eTag
иlast-modified
сохраняются. - в конце внутреннее состояние запроса сбрасывается, делая его многоразовым —
headMethod.releaseConnection()
2.2.3. Сделайте http-вызов из-за прокси
Если вы находитесь за прокси-сервером, вы можете легко настроить HTTP-вызов, установив прокси-сервер org.apache.http.HttpHost
в RequestConfig
:
HTTP-вызов за прокси
1
2
3
4
5
6
|
HttpHost proxy = new HttpHost( "xx.xx.xx.xx" , 8080 , "http" ); RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(TIMEOUT * 1000 ) .setConnectTimeout(TIMEOUT * 1000 ) .setProxy(proxy) .build(); |
Ресурсы
Исходный код — GitHub
- podcastpedia-batch — задание на добавление новых подкастов из файла в каталог подкастов, использует код, представленный в посте, для сохранения заголовков eTag и lastModified; это все еще в стадии разработки. Пожалуйста, сделайте запрос, если у вас есть предложения по улучшению
Web
- Протокол передачи гипертекста — HTTP / 1.1
- Репозиторий Maven
Ссылка: | Как использовать новый Apache Http Client для отправки HEAD-запроса от нашего партнера по JCG Адриана Матеи в блоге Codingpedia.org . |