如果您已更新Apache HTTP Client代码以使用最新的库(在撰写本文时,它是4.2.x版本的httpclient 4.3.5版本和httpcore 4.3.2版本),您会注意到某些类(例如org.apache.http.impl.client.DefaultHttpClient
或org.apache.http.params.HttpParams
已被弃用。 好吧,我去过那里,所以在这篇文章中,我将介绍如何通过使用新类摆脱警告。
1.
我将用于演示的用例很简单:我有一个批处理作业,以检查是否有新的情节可用于播客。 为了避免在没有新情节的情况下必须获取和解析提要,我先验证自上次调用以来eTag
或提要资源的last-modified
标头是否已更改。 如果供稿发布者支持这些标头,这将起作用,我强烈建议您使用这些标头,因为这样可以节省使用者的带宽和处理能力。
那么它是如何工作的呢? 最初,当将新的播客添加到Podcastpedia.org目录时,我检查供稿资源的标头是否存在,如果存在,则将其存储在数据库中。 为此,我借助Apache Http Client对提要的URL执行HTTP HEAD请求。 根据超文本传输协议HTTP / 1.1 rfc2616 ,HTTP头中包含的响应HEAD请求的元信息应与响应GET请求发送的信息相同。
在以下各节中,我将介绍在升级到Apache Http Client的4.3.x版本之前和之后,代码在Java中的实际外观。
2.迁移到4.3.x版本
软件依赖
要构建我的项目,该项目现在可以在GitHub – Podcastpedia-batch上使用 ,我正在使用maven,因此在下面列出了Apache Http Client所需的依赖项:
2.1.1。 之前
Apache Http Client依赖项4.2.x
<!-- 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依赖项
<!-- 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>
Apache Http Client的HEAD请求
2.2.1。 v4.2.x之前
使用Apache HttpClient执行HEAD请求的示例
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 existentorg.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之后
带有Apache Http Client v 4.3.x的HEAD请求示例
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 existentHeader 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行]取代,可以在其中设置套接字和连接超时。 稍后在构建HttpClient
时使用此配置(第13行)
剩下的代码很简单:
- HEAD请求被执行(第17行)
- 如果存在,则
eTag
和last-modified
标头将保留。 - 最后,重置请求的内部状态,使其可重用–
headMethod.releaseConnection()
2.2.3。 从代理后面进行http呼叫
如果您位于代理后面,则可以通过在RequestConfig
上设置org.apache.http.HttpHost
代理主机来轻松配置HTTP调用:
代理后面的HTTP调用
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 –将新的Podcast从文件添加到Podcast目录的工作,使用帖子中提供的代码来保留eTag和lastModified标头; 它仍在进行中。 如果您有任何改进建议,请提出要求
网页
- 超文本传输协议-HTTP / 1.1
- Maven仓库
- HttpComponents客户端
翻译自: https://www.javacodegeeks.com/2014/08/how-to-use-the-new-apache-http-client-to-make-a-head-request.html