Если вы обновили свой код 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 . |